home *** CD-ROM | disk | FTP | other *** search
/ Aminet 2 / Aminet AMIGA CDROM (1994)(Walnut Creek)[Feb 1994][W.O. 44790-1].iso / Aminet / gfx / edit / TSMrph23s.lha / TSM23s.lha / TSMorph.c < prev    next >
C/C++ Source or Header  |  1993-10-08  |  109KB  |  3,476 lines

  1. // TSMorph - Amiga Morphing program
  2. // Copyright (C) © 1993  Topicsave Limited
  3.  
  4. // This program is free software; you can redistribute it and/or modify
  5. // it under the terms of the GNU General Public License as published by
  6. // the Free Software Foundation; either version 2 of the License, or
  7. // any later version.
  8.  
  9. // This program is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12. // GNU General Public License for more details.
  13.  
  14. // You should have received a copy of the GNU General Public License
  15. // along with this program; if not, write to the Free Software
  16. // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17.  
  18. // mpaddock@cix.compulink.co.uk
  19.  
  20. //    $Author: M_J_Paddock $
  21. //    $Date: 1993/09/12 14:22:47 $
  22. //    $Revision: 1.16 $
  23.  
  24. // include normally precompiled headers if required
  25. #ifndef TSMORPH_H
  26. #include "TSMorph.h"
  27. #endif
  28.  
  29. /* Disable CTRL-C checking    */
  30. int CXBRK(void) { return(0); }
  31. int chkabort(void) { return(0); }
  32.  
  33. /* Define all the Library bases    */
  34. struct Library    *IntuitionBase,
  35.                     *GfxBase,
  36.                     *LayersBase,
  37.                     *InputBase,
  38.                     *IFFParseBase,
  39.                     *GadToolsBase,
  40.                     *AslBase,
  41.                     *UtilityBase,
  42.                     *DiskfontBase,
  43.                     *AmigaGuideBase,
  44.                     *IconBase,
  45.                     *ReqToolsBase,
  46.                     *RexxSysBase,
  47.                     *DCTVBase;
  48.  
  49. struct OpalBase *OpalBase;
  50.  
  51. /* Table of system gadget sizes
  52.  * See TSMorph.h for definitions
  53.  */
  54. extern struct gadgetsizing gs[] = {
  55.     {SYSISIZE_LOWRES,13,11,16,11,13,11,16,11,13,11,15,18,18, 7, 9},
  56.     {SYSISIZE_MEDRES,18,10,16,10,18,11,16,10,18,11,20,24,24,10,13}
  57. };
  58.  
  59. extern UWORD                         Mode             = NONE;
  60. extern struct List                PointList     = {0};
  61. extern struct Picture             Pic1            = {0},
  62.                                         Pic2            = {0};
  63. extern BOOL                         Pic1_Open    = FALSE;
  64. extern BOOL                         Pic2_Open    = FALSE;
  65. extern struct FileRequester     *filereq        = NULL;
  66. extern struct FileRequester     *sfilereq    = NULL;
  67. extern BOOL                         Saved         = TRUE;
  68. char                         savedfilename[256]    = "";
  69. extern LONG                            Width            = 0,
  70.                                         Height        = 0;
  71. extern LONG                            SinglePicture            = 0;
  72. extern BOOL                         Zoom            = FALSE;
  73. extern BOOL                         ZoomAllowed    = TRUE;
  74. extern BOOL                            PaletteAllowed            = TRUE;
  75. extern char                         **ArgArray                = NULL;
  76. extern char                         **ArgArraySettings    = NULL;
  77. extern AMIGAGUIDECONTEXT         handle         = NULL;
  78. extern BOOL                            palette        = TRUE;
  79. extern BOOL                            CreateIcons = TRUE;
  80. extern BOOL                            CreateIconsR = FALSE;/* TRUE if to write Render Icons    */
  81. extern BOOL                            CreateIconsP = TRUE;    /* TRUE if to write prefs Icons    */
  82. extern BOOL                            KeepSettings = TRUE; /* TRUE to save settings on quit */
  83. extern ULONG                        DX=0;
  84. extern ULONG                        DY=0;
  85. char                            LoadScript[128] = "Rexx/Loadscript";
  86. char                            PreScript[128] = "Rexx/Prescript";
  87. char                            PostScript[128] = "Rexx/Postscript";
  88. char                            PreviewScript[128] = "Rexx/Preview";
  89. char                            ScreenName[128] = "";
  90. char                            ScreenNameR[128] = "";
  91. char                            CustomName[128] = "";
  92. extern ULONG                        CustomDepth = 4;
  93. extern BOOL                            OpenedScreen = FALSE;/* Did we open the screen            */
  94. extern ULONG                        Depth=2;
  95. extern ULONG                        RenderMode=0;
  96. extern ULONG                        SaveFormat=0;
  97. extern ULONG                        Quality=75;
  98. extern ULONG                        ASig            = 0;
  99. extern ULONG                        OpenMode        = 0;
  100. extern int                            changedboxcount    = 0;    // Used to redraw points after resizing BOTH windows
  101. extern UWORD                        n=0;                            // Holds screen resolution
  102. extern LONG                         MaxWidth        = 0;    // Max x of points
  103. extern LONG                            MaxHeight    = 0;    // Max y of points
  104. extern BOOL                            AntiAlias    = FALSE;    // Anti Alias?
  105. extern BOOL                            GHelp            = FALSE;    // Gadget Help?
  106.  
  107. struct MsgPort        *WMsgPortp;            // Message port for Picture Windows
  108. ULONG                 IDCMPFlags;            // IDCMP flags for windows
  109. LONG                     Start;                // Start frame
  110. struct NewAmigaGuide        nag     = {NULL};    // .guide stuff
  111.  
  112. /* Mapping for Boopsi gadgets    */
  113. struct TagItem MapToIdcmp[] = {
  114.     {PGA_Top,ICSPECIAL_CODE},
  115.     {GA_ID,ICSPECIAL_CODE},
  116.     {TAG_END,}
  117. };
  118.  
  119. /* Properties for IFF read    */
  120. extern LONG props[] = {    ID_ILBM,    ID_BMHD,    // Just need BitMapHeader
  121.                         ID_ILBM,    ID_CAMG,            // CAMG (not sure why)
  122.                         ID_ILBM, ID_CMAP,            // And ColourMap
  123.                         TAG_DONE };
  124.  
  125. extern LONG stops[] = {    ID_ILBM,    ID_BODY,    // Stop on Body chunk
  126.                         TAG_DONE };
  127.  
  128. extern LONG nowt[] = { TAG_DONE };            // Nothing else is required
  129.  
  130. extern LONG FrameNumber = 0;                    // Current frame number
  131.  
  132. /* Wait pointer */
  133. extern USHORT __chip BusyPointerData[] =
  134. {
  135.     0x0000,0x0000,
  136.     0x0400,0x07C0,0x0000,0x07C0,0x0100,0x0380,0x0000,0x07E0,
  137.     0x07C0,0x1FF8,0x1FF0,0x3FEC,0x3FF8,0x7FDE,0x3FF8,0x7FBE,
  138.     0x7FFC,0xFF7F,0x7EFC,0xFFFF,0x7FFC,0xFFFF,0x3FF8,0x7FFE,
  139.     0x3FF8,0x7FFE,0x1FF0,0x3FFC,0x07C0,0x1FF8,0x0000,0x07E0,
  140.     0x0000,0x0000,
  141. };
  142.  
  143.  
  144. /* Version string for CLI version */
  145. char *Version = "$VER: TSMorph 2.3 (6.10.93)";
  146.  
  147. /* Display About requester
  148.  * using reqtools.library if available
  149.  */
  150. void
  151. About(void) {
  152.     UBYTE *body = "TSMorph\n©1993 Topicsave Ltd/M J Paddock\n\n"
  153.                       "TSMorph comes with ABSOLUTELY NO WARRANTY\n\n"
  154.                       "This is free software, and you are welcome to redistribute it\n"
  155.                       "under certain conditions\n\n"
  156.                       "See file COPYING for details";
  157.     UBYTE *title = "TSMorph 2.3 (6.10.93)";
  158.     UBYTE *gad = "OK";
  159.     struct EasyStruct EasyStruct = {
  160.           sizeof(struct EasyStruct),
  161.         0,
  162.         NULL,
  163.         NULL,
  164.         NULL
  165.     };
  166.     DisableWindows(DI_About);
  167.     if (ReqToolsBase) {
  168.         rtEZRequestTags(body,"_OK",NULL,NULL,
  169.                             RT_Window,        TSMorphWnd,
  170.                             RTEZ_ReqTitle,    title,
  171.                             RTEZ_Flags,        EZREQF_CENTERTEXT,
  172.                             RT_Underscore,    '_',
  173.                             TAG_END);
  174.     }
  175.     else {
  176.         EasyStruct.es_Title = title;
  177.         EasyStruct.es_TextFormat = body;
  178.         EasyStruct.es_GadgetFormat = gad;
  179.         EasyRequestArgs(TSMorphWnd,&EasyStruct,NULL,NULL);
  180.     }
  181.     EnableWindows();
  182. }
  183.  
  184. /* The main procedure    */
  185. void
  186. main(int argc,char **argv) {
  187.  BOOL                 OkFlag        = FALSE;        // Still running ok
  188.  struct IOStdReq    InputIO;                        // Input device to check Shift key
  189.  struct Message     *Message;                    // To discard messages from ports
  190.  struct WBStartup *argmsg;                        // Workbench stuff
  191.  struct WBArg         *wb_arg;                        // Workbench arguments
  192.  struct Window        *oldWindowPtr;                // Retain old pointer for system requesters
  193.  struct Process    *process;                    // This process for system requesters
  194.  char                 *e                = NULL;        // Main error message string
  195.  char                 *e1            = NULL;        // Variable part of error message
  196.  char                 *filename;                    // General file name
  197.  LONG                    hnum            = 0;            // Help to display on an error message
  198.  
  199.  /* Initalise list of points    */
  200.  NewList(&PointList);
  201.  // try and open optional libraries
  202.  DCTVBase = OpenLibrary("dctv.library",3L);
  203.  OpalBase = (struct OpalBase *)OpenLibrary("opal.library",0L);
  204.  ReqToolsBase = OpenLibrary("reqtools.library",38);
  205.  /* If we can open amigaguide.library
  206.   * then set up the help stuff
  207.   */
  208.  if (AmigaGuideBase = OpenLibrary ("amigaguide.library", 34L)) {
  209.   nag.nag_BaseName        = "TSMorph";
  210.   nag.nag_Name                = "TSMorph.guide";
  211.   nag.nag_ClientPort        = "TSMorph_HELP";
  212.   nag.nag_Context            = context;
  213.   nag.nag_Flags            = HTF_NOACTIVATE;
  214.   nag.nag_PubScreen        = NULL;
  215.   if (handle = OpenAmigaGuideAsync(&nag, NULL)) {
  216.    ASig = AmigaGuideSignal(handle);
  217.   }
  218.  }
  219.  /* Open all the libraries/devices/message ports/file requesters etc.    */
  220.  if (IntuitionBase = OpenLibrary("intuition.library",37L)) {
  221.   if (RexxSysBase = OpenLibrary("rexxsyslib.library",0L)) {
  222.   if (IconBase = OpenLibrary("icon.library",37L)) {
  223.    if (IFFParseBase = OpenLibrary("iffparse.library",37L)) {
  224.     if (!OpenDevice("input.device",NULL,(struct IORequest *)&InputIO,NULL)) {
  225.      InputBase = (struct Library *)InputIO.io_Device;
  226.      if (GfxBase = OpenLibrary("graphics.library",37L)) {
  227.       if (LayersBase = OpenLibrary("layers.library",37L)) {
  228.        if (GadToolsBase = OpenLibrary("gadtools.library",37L)) {
  229.         if (AslBase = OpenLibrary("asl.library",37L)) {
  230.          if (UtilityBase = OpenLibrary("utility.library",37)) {
  231.           if (DiskfontBase = OpenLibrary("diskfont.library",36)) {
  232.            if (WMsgPortp = CreateMsgPort()) {
  233.             if (filereq = (struct FileRequest *)AllocFileRequest()) {
  234.               /* Read all the parameters/tooltypes/settings file    */
  235.               MyArgArrayInit(argc,argv);
  236.               InitParams(TRUE);
  237.               /* Open custom screen if required                */
  238.               if (OpenCustomScreen()) {
  239.                if (PubScreenName && *PubScreenName) {
  240.                 /* Since the screen now exists reopen amigaguide on it! */
  241.                 if (handle) {
  242.                  CloseAmigaGuide(handle);
  243.                  handle = NULL;
  244.                 }
  245.                 if (AmigaGuideBase) {
  246.                  nag.nag_PubScreen        = PubScreenName;
  247.                  if (handle = OpenAmigaGuideAsync(&nag, NULL)) {
  248.                   ASig = AmigaGuideSignal(handle);
  249.                  }
  250.                 }
  251.                }
  252.                /* Update the Info window menus and open    */
  253.                if (!SetupScreen()) {
  254.                 if (!OpenTSMorphWindow()) {
  255.                  /* Set up system requester redirection    */
  256.                  process = (struct Process *)FindTask(NULL);
  257.                  oldWindowPtr = process->pr_WindowPtr;
  258.                  process->pr_WindowPtr = TSMorphWnd;
  259.                  /* Activate the window and disable        */
  260.                  ActivateWindow(TSMorphWnd);
  261.                  DisableWindows(DI_LoadBrush);
  262.                  /* Load brushes if possible                    */
  263.                  LoadBrushes();
  264.                  /* No filename as yet                            */
  265.                     *savedfilename = 0;
  266.                     if (argc) {
  267.                     if (filename = ArgString(ArgArray,"FILES",NULL)) {
  268.                    MyOpen(filename,FALSE,TRUE);                // From the CLI and FILES parameter supplied
  269.                   }
  270.                  }
  271.                  else {
  272.                     argmsg = (struct WBStartup *)argv;
  273.                          if (argmsg->sm_NumArgs > 1) {
  274.                      wb_arg = argmsg->sm_ArgList;
  275.                      wb_arg++;
  276.                      if (wb_arg->wa_Lock) {
  277.                         NameFromLock(wb_arg->wa_Lock,savedfilename,256);
  278.                        }
  279.                       if (AddPart(savedfilename,wb_arg->wa_Name,256)) {
  280.                        MyOpen(savedfilename,FALSE,TRUE);        // From the WB and project supplied
  281.                      }
  282.                     }
  283.                  }
  284.                  /* Enable the windows and do the main stuff    */
  285.                  EnableWindows();
  286.                  doMsgLoop();
  287.                  if (KeepSettings) {
  288.                   SaveSettings("ENV:TSMorph/TSMorph.prefs");    // save settings for next run
  289.                  }
  290.                  /* Close everything down in reverse order
  291.                   * Setting up error message if required
  292.                   */
  293.                  if (Pic1_Open) {
  294.                   CloseAPicture(&Pic1);
  295.                   Pic1_Open = FALSE;
  296.                  }
  297.                  if (Pic2_Open) {
  298.                   CloseAPicture(&Pic2);
  299.                   Pic2_Open = FALSE;
  300.                  }
  301.                  DeleteAllPoints();
  302.                  if (ControlWindow) {
  303.                   CloseControlWindow();
  304.                  }
  305.                  process->pr_WindowPtr = oldWindowPtr;
  306.                  OkFlag = TRUE;
  307.                 }
  308.                 CloseTSMorphWindow();
  309.                 if (!OkFlag && !e) {
  310.                  e = "Failure %s";                    // e and e1 to save memory as e is reused
  311.                  e1 = "opening TSMorph Window";
  312.                  hnum = HE_OMorph;
  313.                 }
  314.                }
  315.                CloseDownScreen();
  316.                if (!OkFlag && !e) {
  317.                 e = "Failure %s";
  318.                 e1 = "setting up screen";
  319.                 hnum = HE_Screen;
  320.                }
  321.               }
  322.               else {
  323.                // Displayed error message elsewhere
  324.                OkFlag = TRUE;
  325.               }
  326.               MyArgArrayDone();
  327.               FreeFileRequest(filereq);
  328.             }
  329.             if (!OkFlag && !e) {
  330.              e = "Unable to %s";
  331.              e1 = "Allocate FileRequest";
  332.              hnum = HE_FileReq;
  333.             }
  334.             Forbid();
  335.             while (Message = GetMsg(WMsgPortp)) {
  336.              ReplyMsg(Message);
  337.             }
  338.             DeleteMsgPort(WMsgPortp);
  339.             Permit();
  340.            }
  341.            if (!OkFlag && !e) {
  342.             e = "Unable to %s";
  343.             e1 = "Create Window Message Port";
  344.             hnum = HE_WPort;
  345.            }
  346.            CloseLibrary(DiskfontBase);
  347.           }
  348.           if (!OkFlag && !e) {
  349.            e = "Can not Open %s";
  350.            e1= "diskfont.library(36)";
  351.            hnum = HE_Library;
  352.                }
  353.           CloseLibrary(UtilityBase);
  354.          }
  355.          if (!OkFlag && !e) {
  356.           e = "Can not Open %s";
  357.           e1 = "utility.library(37)";
  358.           hnum = HE_Library;
  359.          }
  360.          CloseLibrary(AslBase);
  361.         }
  362.         if (!OkFlag && !e) {
  363.          e = "Can not Open %s";
  364.          e1 = "asl.library(37)";
  365.          hnum = HE_Library;
  366.         }
  367.         CloseLibrary(GadToolsBase);
  368.        }
  369.        if (!OkFlag && !e) {
  370.         e = "Can not Open %s";
  371.         e1 = "gadtools.library(37)";
  372.         hnum = HE_Library;
  373.        }
  374.        CloseLibrary(LayersBase);
  375.       }
  376.       if (!OkFlag && !e) {
  377.        e = "Can not Open %s";
  378.        e1 = "layers.library(37)";
  379.        hnum = HE_Library;
  380.       }
  381.       CloseLibrary(GfxBase);
  382.      }
  383.      if (!OkFlag && !e) {
  384.       e = "Can not Open %s";
  385.       e1 = "graphics.library(37)";
  386.       hnum = HE_Library;
  387.      }
  388.      CloseDevice(&InputIO);
  389.     }
  390.     if (!OkFlag && !e) {
  391.      e = "Can not Open %s";
  392.      e1 = "input.device";
  393.      hnum = HE_IDevice;
  394.     }
  395.     CloseLibrary(IFFParseBase);
  396.    }
  397.    if (!OkFlag && !e) {
  398.     e = "Can not Open %s";
  399.     e1 = "iffparse.library(37)";
  400.     hnum = HE_Library;
  401.    }
  402.      CloseLibrary(IconBase);
  403.   }
  404.   if (!OkFlag && !e) {
  405.    e = "Can not Open %s";
  406.    e1 = "icon.library(37)";
  407.    hnum = HE_Library;
  408.   }
  409.      CloseLibrary(RexxSysBase);
  410.   }
  411.   if (!OkFlag && !e) {
  412.    e = "Can not Open %s";
  413.    e1 = "rexxsyslib.library(0)";
  414.    hnum = HE_Library;
  415.   }
  416.   if (!OkFlag) {
  417.    Error(e,"Quit",e1,hnum);            // Display error message if it failed
  418.   }
  419.  }
  420.  if (AmigaGuideBase) {
  421.   if (handle) {
  422.      CloseAmigaGuide(handle);
  423.   }
  424.   CloseLibrary(AmigaGuideBase);
  425.  }
  426.  if (OpalBase) {
  427.   CloseLibrary((struct Library *)OpalBase);
  428.  }
  429.  if (ReqToolsBase) {
  430.   CloseLibrary(ReqToolsBase);
  431.  }
  432.  if (DCTVBase) {
  433.   CloseLibrary(DCTVBase);
  434.  }
  435.  if (OpenedScreen) {
  436.   CloseCustomScreen();
  437.  }
  438.  if (IntuitionBase) {
  439.   CloseLibrary(IntuitionBase);
  440.  }
  441. }
  442.  
  443. /* Open and image in a window
  444.  * returns    : TRUE or FALSE for sucess failure
  445.  * filename    : Name of file, can be NULL in which case ASL file requester is displayed
  446.  * pic        : pointer to a structure to hold all the stuff
  447.  * GUI        : TRUE or FALSE to display error message on failure
  448.  */
  449. BOOL
  450. openAPicture(char *filename,struct Picture *pic,BOOL GUI) {
  451.  char dirname[257];            // full filename from ASL requester or FrameNumber
  452.  char *ifilename    = NULL;    // filename to use
  453.  char *e             = NULL;    // first part of error message
  454.  char *e1             = NULL;    // 2nd part of error message
  455.  int i;                            // Loop counter for bit planes
  456.  LONG hnum            = 0;        // Help number for error
  457.  /* Set file name from input supplied
  458.   * or by using ASL file requester
  459.   */
  460.  if (filename) {
  461.   if ((SinglePicture == 2) || (SinglePicture == 3)) {
  462.    sprintf(dirname,filename,FrameNumber);        // Add in frame number
  463.    ifilename = dirname;
  464.   }
  465.   else {
  466.    ifilename = filename;
  467.   }
  468.  }
  469.  else {
  470.   if (AslRequestTags((APTR) filereq,ASL_Hail,(Tag) "TSMorph - Pick ILBM",TAG_DONE)) {
  471.    strncpy(dirname,filereq->rf_Dir,256);
  472.    if (AddPart(dirname,filereq->rf_File,256)) {
  473.     ifilename=dirname;
  474.    }
  475.   }
  476.  }
  477.  /* If we now have a file name then find the screen (passed in PUBSCREEN=)
  478.   * determine its resolution and get some data
  479.   */
  480.  if (ifilename) {
  481.   if (pic->Screen = LockPubScreen(PubScreenName)) {
  482.    if (pic->DRI = GetScreenDrawInfo(pic->Screen)) {
  483.     /* Load the image using IFF stuff
  484.      * and do some validation and set some gadgets
  485.      */
  486.     if (pic->ilbm = (struct ILBMInfo *)AllocMem(sizeof(struct ILBMInfo),MEMF_PUBLIC|MEMF_CLEAR)) {
  487.      if (!MyLoadBrush(pic,ifilename)) {
  488.       e = (char *)-1;
  489.       GUI = FALSE;    // already displayed message
  490.      }
  491.      else {
  492.       if (pic == &Pic1) {
  493.          if ((Pic1.ilbm->Bmhd.w < MaxWidth) ||
  494.            (Pic1.ilbm->Bmhd.h < MaxHeight)) {
  495.         e = "Image smaller than points";
  496.         hnum = HE_ISmall;
  497.        }
  498.       }
  499.       else {
  500.        if ((Pic1.ilbm->Bmhd.w != Pic2.ilbm->Bmhd.w) ||
  501.            (Pic1.ilbm->Bmhd.w != Pic2.ilbm->Bmhd.w)) {
  502.         e = "Images different sizes";
  503.         hnum = HE_IDifferent;
  504.        }
  505.        else {
  506.         Width = Pic1.ilbm->Bmhd.w;
  507.         Height = Pic1.ilbm->Bmhd.h;
  508.           GT_SetGadgetAttrs(TSMorphGadgets[GDX_Width],TSMorphWnd,NULL,
  509.                                 GTNM_Number,Width,
  510.                                 TAG_END );
  511.           GT_SetGadgetAttrs(TSMorphGadgets[GDX_Height],TSMorphWnd,NULL,
  512.                                 GTNM_Number,Height,
  513.                                 TAG_END );
  514.        }
  515.       }
  516.       /* If Zoom is allowed then we always display the Zoom bitmap
  517.        * This is either 2x the normal bit map or just use the top left corner
  518.        */
  519.       if (!e) {
  520.        if (ZoomAllowed) {
  521.         InitBitMap(&(pic->BitMap),min(min(pic->ilbm->Bmhd.nPlanes,8),pic->Screen->BitMap.Depth),pic->ilbm->Bmhd.w<<1,pic->ilbm->Bmhd.h<<1);
  522.            for (i=0;
  523.                  (i < pic->ilbm->Bmhd.nPlanes) && (i < 8) && (i < pic->Screen->BitMap.Depth) && !e; // Allow up to 8 bitplanes
  524.                  ++i) {
  525.            if (!(pic->BitMap.Planes[i] = AllocRaster(pic->ilbm->Bmhd.w<<1,pic->ilbm->Bmhd.h<<1))) {
  526.           e = "Unable to Allocate %s";
  527.           e1 = "Zoom raster";
  528.           hnum = HE_ZRaster;
  529.          }
  530.           }
  531.           if (!e) {
  532.            pic->BitScaleArgs.bsa_SrcX         = 0;
  533.            pic->BitScaleArgs.bsa_SrcY         = 0;
  534.            pic->BitScaleArgs.bsa_SrcWidth     = pic->ilbm->Bmhd.w;
  535.            pic->BitScaleArgs.bsa_SrcHeight     = pic->ilbm->Bmhd.h;
  536.            pic->BitScaleArgs.bsa_DestX         = 0;
  537.            pic->BitScaleArgs.bsa_DestY         = 0;
  538.            pic->BitScaleArgs.bsa_DestWidth     = pic->ilbm->Bmhd.w<<1;
  539.            pic->BitScaleArgs.bsa_DestHeight = pic->ilbm->Bmhd.h<<1;
  540.            pic->BitScaleArgs.bsa_XSrcFactor = 1;
  541.            pic->BitScaleArgs.bsa_XDestFactor= 2;
  542.            pic->BitScaleArgs.bsa_YSrcFactor = 1;
  543.            pic->BitScaleArgs.bsa_YDestFactor= 2;
  544.            pic->BitScaleArgs.bsa_SrcBitMap     = pic->ilbm->brbitmap;
  545.            pic->BitScaleArgs.bsa_DestBitMap = &(pic->BitMap);
  546.            pic->BitScaleArgs.bsa_Flags         = 0;
  547.            /* Either scale image 2x or straight copy    */
  548.             if (Zoom) {
  549.              BitMapScale(&(pic->BitScaleArgs));
  550.             }
  551.            else {
  552.             BltBitMap(pic->ilbm->brbitmap,0,0,
  553.                            &(pic->BitMap),0,0,
  554.                            pic->ilbm->Bmhd.w,pic->ilbm->Bmhd.h,
  555.                            0xC0,0xff,NULL);
  556.            }
  557.           }
  558.          }
  559.         }
  560.       if (!e) {
  561.        pic->Left = 0;    //    Need to do this as Pic structures can be closed and reopened
  562.        pic->Top = 0;
  563.        /* Allocate all gadgets and images    */
  564.        if (pic->BotGad = (struct Gadget *)NewObject(NULL,"propgclass",
  565.          PGA_Freedom,        FREEHORIZ,
  566.          PGA_NewLook,        TRUE,
  567.          PGA_Borderless,    TRUE,
  568.          PGA_Top,                pic->Left,
  569.          PGA_Visible,        pic->ilbm->Bmhd.w<<Zoom,
  570.          PGA_Total,            pic->ilbm->Bmhd.w<<Zoom,
  571.          ICA_TARGET,            ICTARGET_IDCMP,
  572.          GA_Left,                pic->Screen->WBorLeft - 1,
  573.          GA_Height,            SIZEIMAGE_H(n) - 4,
  574.          GA_RelBottom,        -SIZEIMAGE_H(n) + 3,
  575.          GA_RelWidth,        -(SIZEIMAGE_W(n)+LEFTIMAGE_W(n)+RIGHTIMAGE_W(n)+pic->Screen->WBorLeft+1),
  576.          GA_ID,                LEFT_RIGHT_GADGET,
  577.          GA_GZZGadget,        TRUE,
  578.          GA_Immediate,        TRUE,
  579.          GA_RelVerify,        TRUE,
  580.          GA_BottomBorder,    TRUE,
  581.          ICA_MAP,                MapToIdcmp,
  582.          GA_UserData,        pic,
  583.          TAG_END)) {
  584.         if (pic->SideGad = (struct Gadget *)NewObject(NULL,"propgclass",
  585.           PGA_Freedom,        FREEVERT,
  586.           PGA_NewLook,        TRUE,
  587.           PGA_Borderless,    TRUE,
  588.           PGA_Top,            pic->Top,
  589.           PGA_Visible,        pic->ilbm->Bmhd.h<<Zoom,
  590.           PGA_Total,            pic->ilbm->Bmhd.h<<Zoom,
  591.           ICA_TARGET,        ICTARGET_IDCMP,
  592.           GA_Top,                pic->Screen->WBorTop + pic->Screen->Font->ta_YSize + 2,
  593.           GA_Width,            VSCROLL_W(n),
  594.           GA_RelRight,        -VSCROLL_L(n),
  595.           GA_RelHeight,        -(pic->Screen->WBorTop+pic->Screen->Font->ta_YSize+3+UPIMAGE_H(n)+DOWNIMAGE_H(n)+SIZEIMAGE_H(n)),
  596.           GA_ID,                UP_DOWN_GADGET,
  597.           GA_GZZGadget,        TRUE,
  598.           GA_Immediate,        TRUE,
  599.           GA_RelVerify,        TRUE,
  600.           GA_RightBorder,    TRUE,
  601.           GA_Previous,        pic->BotGad,
  602.           ICA_MAP,            MapToIdcmp,
  603.           GA_UserData,        pic,
  604.           TAG_END)) {
  605.          if (pic->Limage = (struct Image *)NewObject(NULL,"sysiclass",
  606.            SYSIA_DrawInfo,    pic->DRI,
  607.            SYSIA_Which,        LEFTIMAGE,
  608.            SYSIA_Size,        SYSISIZE(n),
  609.            TAG_END)) {
  610.           if (pic->Rimage = (struct Image *)NewObject(NULL,"sysiclass",
  611.             SYSIA_DrawInfo,pic->DRI,
  612.             SYSIA_Which,    RIGHTIMAGE,
  613.             SYSIA_Size,        SYSISIZE(n),
  614.             TAG_END)) {
  615.            if (pic->Dimage = (struct Image *)NewObject(NULL,"sysiclass",
  616.              SYSIA_DrawInfo,    pic->DRI,
  617.              SYSIA_Which,        DOWNIMAGE,
  618.              SYSIA_Size,        SYSISIZE(n),
  619.              TAG_END)) {
  620.             if (pic->Uimage = (struct Image *)NewObject(NULL,"sysiclass",
  621.               SYSIA_DrawInfo,    pic->DRI,
  622.               SYSIA_Which,        UPIMAGE,
  623.               SYSIA_Size,        SYSISIZE(n),
  624.               TAG_END)) {
  625.              if (pic->Lgad = (struct Gadget *)NewObject(NULL,"buttongclass",
  626.                ICA_TARGET,            ICTARGET_IDCMP,
  627.                GA_RelRight,        -(SIZEIMAGE_W(n)+RIGHTIMAGE_W(n)+LEFTIMAGE_W(n)-1),
  628.                GA_RelBottom,        -SIZEIMAGE_H(n)+1,
  629.                GA_Height,            LEFTIMAGE_H(n),
  630.                GA_Width,            LEFTIMAGE_W(n),
  631.                GA_ID,                LEFT_GADGET,
  632.                GA_GZZGadget,        TRUE,
  633.                GA_Immediate,        TRUE,
  634.                GA_RelVerify,        TRUE,
  635.                GA_BottomBorder,    TRUE,
  636.                GA_Previous,        pic->SideGad,
  637.                ICA_MAP,                MapToIdcmp,
  638.                GA_Image,            pic->Limage,
  639.                GA_UserData,        pic,
  640.                TAG_END)) {
  641.               if (pic->Rgad = (struct Gadget *)NewObject(NULL,"buttongclass",
  642.                 ICA_TARGET,        ICTARGET_IDCMP,
  643.                 GA_RelRight,        -(SIZEIMAGE_W(n)+RIGHTIMAGE_W(n)-1),
  644.                 GA_RelBottom,        -SIZEIMAGE_H(n)+1,
  645.                 GA_Height,            LEFTIMAGE_H(n),
  646.                 GA_Width,            LEFTIMAGE_W(n),
  647.                 GA_ID,                RIGHT_GADGET,
  648.                 GA_GZZGadget,        TRUE,
  649.                 GA_Immediate,        TRUE,
  650.                 GA_RelVerify,        TRUE,
  651.                 GA_BottomBorder,    TRUE,
  652.                 GA_Previous,        pic->Lgad,
  653.                 ICA_MAP,            MapToIdcmp,
  654.                 GA_Image,            pic->Rimage,
  655.                 GA_UserData,        pic,
  656.                 TAG_END)) {
  657.                if(pic->Ugad = (struct Gadget *)NewObject(NULL,"buttongclass",
  658.                  ICA_TARGET,        ICTARGET_IDCMP,
  659.                  GA_RelRight,        -SIZEIMAGE_W(n)+1,
  660.                  GA_RelBottom,    -(SIZEIMAGE_H(n)+UPIMAGE_H(n)+DOWNIMAGE_H(n)-1),
  661.                  GA_Height,        UPIMAGE_H(n),
  662.                  GA_Width,            UPIMAGE_W(n),
  663.                  GA_ID,                UP_GADGET,
  664.                  GA_GZZGadget,    TRUE,
  665.                  GA_Immediate,    TRUE,
  666.                  GA_RelVerify,    TRUE,
  667.                  GA_RightBorder,    TRUE,
  668.                  GA_Previous,        pic->Rgad,
  669.                  ICA_MAP,            MapToIdcmp,
  670.                  GA_Image,            pic->Uimage,
  671.                  GA_UserData,        pic,
  672.                  TAG_END)) {
  673.                 if (pic->Dgad = (struct Gadget *)NewObject(NULL,"buttongclass",
  674.                   ICA_TARGET,            ICTARGET_IDCMP,
  675.                   GA_RelRight,        -SIZEIMAGE_W(n)+1,
  676.                   GA_RelBottom,        -(SIZEIMAGE_H(n)+DOWNIMAGE_H(n)-1),
  677.                   GA_Height,            DOWNIMAGE_H(n),
  678.                   GA_Width,            DOWNIMAGE_W(n),
  679.                   GA_ID,                DOWN_GADGET,
  680.                   GA_GZZGadget,        TRUE,
  681.                   GA_Immediate,        TRUE,
  682.                   GA_RelVerify,        TRUE,
  683.                   GA_RightBorder,    TRUE,
  684.                   GA_Previous,        pic->Ugad,
  685.                   ICA_MAP,                MapToIdcmp,
  686.                   GA_Image,            pic->Dimage,
  687.                   GA_UserData,        pic,
  688.                   TAG_END)) {
  689.                   /* Set up size of shrunk window    */
  690.                   pic->Zoom.Left     = 0;
  691.                   pic->Zoom.Top         = pic->Screen->Font->ta_YSize+1;
  692.                   pic->Zoom.Width     = max(ZOOMIMAGE_W(n)+DEPTHIMAGE_W(n)+CLOSEIMAGE_W(n)+1,
  693.                                                    pic->Screen->WBorLeft+SIZEIMAGE_W(n)+LEFTIMAGE_W(n)+RIGHTIMAGE_W(n)+7);
  694.                   pic->Zoom.Height     = pic->Screen->WBorTop+pic->Screen->Font->ta_YSize+
  695.                                             SIZEIMAGE_H(n)+UPIMAGE_H(n)+DOWNIMAGE_H(n)+8;
  696.                  /* Copy filename for title and open the window */
  697.                  if (pic->filename     = AllocVec(strlen(ifilename)+1+20,MEMF_PUBLIC|MEMF_CLEAR)) {    // Extra for other frames
  698.                   strcpy(pic->filename,ifilename);
  699.                   if (pic->Win = OpenWindowTags(NULL,
  700.                     WA_Width,            (pic->ilbm->Bmhd.w<<Zoom)+
  701.                                             pic->Screen->WBorLeft+SIZEIMAGE_W(n),
  702.                     WA_Height,        (pic->ilbm->Bmhd.h<<Zoom)+
  703.                                             pic->Screen->WBorTop+pic->Screen->Font->ta_YSize+1+SIZEIMAGE_H(n),
  704.                     WA_AutoAdjust,    TRUE,
  705.                     WA_MaxWidth,        (pic->ilbm->Bmhd.w<<Zoom)+
  706.                                             pic->Screen->WBorLeft+SIZEIMAGE_W(n),
  707.                     WA_MaxHeight,    (pic->ilbm->Bmhd.h<<Zoom)+
  708.                                             pic->Screen->WBorTop + pic->Screen->Font->ta_YSize+1+SIZEIMAGE_H(n),
  709.                     WA_MinWidth,        pic->Zoom.Width,
  710.                     WA_MinHeight,    pic->Zoom.Height,
  711.                     WA_IDCMP,            0,
  712.                     WA_Flags,            WFLG_SIZEGADGET | WFLG_SIZEBRIGHT | WFLG_SIZEBBOTTOM |
  713.                                          WFLG_DRAGBAR | WFLG_DEPTHGADGET | WFLG_CLOSEGADGET |
  714.                                          WFLG_SUPER_BITMAP + WFLG_GIMMEZEROZERO | WFLG_NOCAREREFRESH,
  715.                     WA_Gadgets,        pic->BotGad,
  716.                     WA_Title,            FilePart(pic->filename),
  717.                     WA_ScreenTitle,    pic->filename,
  718.                     WA_PubScreen,    pic->Screen,
  719.                     WA_SuperBitMap,    (ZoomAllowed ? &(pic->BitMap) : pic->ilbm->brbitmap),
  720.                     /* Open image 1 to the right of the control window
  721.                      * Image 2 to the bottom right of the 1st image
  722.                      */
  723.                     WA_Left,             ((pic == &Pic1)?
  724.                                                 ControlWindow->Width:
  725.                                                 ControlWindow->Width+Pic1.Win->Width),
  726.                     WA_Top,             ((pic == &Pic1)?
  727.                                                 ControlWindow->TopEdge:
  728.                                                 Pic1.Win->Height+Pic1.Win->TopEdge),
  729.                           WA_MenuHelp,        TRUE,
  730.                           WA_NewLookMenus,TRUE,
  731.                     TAG_DONE)) {
  732.                    // Enable gadget Help if possible
  733.                          if (IntuitionBase->lib_Version > 38) {
  734.                     HelpControl(pic->Win,HC_GADGETHELP);
  735.                    }
  736.                    /* Set user data to determine window
  737.                     * and use shared message port
  738.                     */
  739.                    pic->Win->UserData  = (BYTE *)pic;
  740.                    pic->Win->UserPort    = WMsgPortp;
  741.                    IDCMPFlags = IDCMP_IDCMPUPDATE | IDCMP_GADGETUP | IDCMP_GADGETDOWN |
  742.                                 IDCMP_NEWSIZE | IDCMP_MOUSEBUTTONS | IDCMP_MOUSEMOVE |
  743.                                 IDCMP_MENUPICK | IDCMP_CLOSEWINDOW | IDCMP_MENUVERIFY |
  744.                                 IDCMP_MENUHELP | IDCMP_RAWKEY | IDCMP_VANILLAKEY |
  745.                                 IDCMP_ACTIVEWINDOW | IDCMP_INACTIVEWINDOW | IDCMP_CHANGEWINDOW |
  746.                                 IDCMP_GADGETHELP;
  747.                    ModifyIDCMP(pic->Win,IDCMPFlags);
  748.                    pic->Win->Flags |= WFLG_REPORTMOUSE;
  749.                          /* Set mode to draw and erase points easily    */
  750.                          SetDrMd(pic->Win->RPort,COMPLEMENT);
  751.                          /* Set the (shared with Control Window) menu
  752.                           * and do some size calculations
  753.                           */
  754.                          if (SetMenuStrip(pic->Win,MyMenu)) {
  755.                     doNewSize(pic);
  756.                     return (TRUE);                            // It all worked !!!
  757.                    }
  758.                    /* Set relevant error message    */
  759.                    if (!e) {
  760.                     e = "Unable to %s";
  761.                     e1 = "SetMenuStrip";
  762.                     hnum = HE_Menu;
  763.                    }
  764.                   }
  765.                   if (!e) {
  766.                    e = "Unable to %s";
  767.                    e1 = "OpenWindowTags";
  768.                    hnum = HE_OWindow;
  769.                   }
  770.                  }
  771.                  if (!e) {
  772.                   e = "Unable to %s";
  773.                   e1 = "AllocMem for Filename";
  774.                   hnum = HE_MemFile;
  775.                  }
  776.                 }
  777.                 if (!e) {
  778.                  e = "Unable to Allocate %s";
  779.                  e1 = "Down Gadget";
  780.                  hnum = HE_AllocGadget;
  781.                 }
  782.                }
  783.                if (!e) {
  784.                 e = "Unable to Allocate %s";
  785.                 e1 = "Up Gadget";
  786.                 hnum = HE_AllocGadget;
  787.                }
  788.               }
  789.               if (!e) {
  790.                e = "Unable to Allocate %s";
  791.                e1 = "Right Gadget";
  792.                hnum = HE_AllocGadget;
  793.               }
  794.              }
  795.              if (!e) {
  796.               e = "Unable to Allocate %s";
  797.               e1 = "Left Gadget";
  798.               hnum = HE_AllocGadget;
  799.              }
  800.             }
  801.             if (!e) {
  802.              e = "Unable to Allocate %s";
  803.              e1 = "Up Image";
  804.              hnum = HE_AllocImage;
  805.             }
  806.            }
  807.            if (!e) {
  808.             e = "Unable to Allocate %s";
  809.             e1 = "Down Image";
  810.             hnum = HE_AllocImage;
  811.            }
  812.           }
  813.           if (!e) {
  814.            e = "Unable to Allocate %s";
  815.            e1 = "Right Image";
  816.            hnum = HE_AllocImage;
  817.           }
  818.          }
  819.          if (!e) {
  820.           e = "Unable to Allocate %s";
  821.           e1 = "Left Image";
  822.           hnum = HE_AllocImage;
  823.          }
  824.         }
  825.         if (!e) {
  826.          e = "Unable to Allocate %s";
  827.          e1 = "Vertical Gadget";
  828.          hnum = HE_AllocGadget;
  829.         }
  830.        }
  831.        if (!e) {
  832.         e = "Unable to Allocate %s";
  833.         e1 = "Horizontal Gadget";
  834.         hnum = HE_AllocGadget;
  835.        }
  836.       }
  837.      }
  838.     }
  839.     if (!e) {
  840.      e = "Unable to %s";
  841.      e1 = "AllocMem for ILBMInfo";
  842.      hnum = HE_AllocILBM;
  843.     }
  844.    }
  845.    if (!e) {
  846.     e = "Unable to %s";
  847.     e1 = "GetScreenDrawInfo";
  848.     hnum = HE_GetDRI;
  849.    }
  850.   }
  851.   if (!e) {
  852.    e = "Unable to LockPubScreen(%s)";
  853.    e1 = PubScreenName;
  854.    hnum = HE_LockScreen;
  855.   }
  856.   /* Clear everything down
  857.    * and display an error message if requested
  858.    */
  859.   CloseAPicture(pic);
  860.   if (GUI)
  861.    Error(e,"OK",e1,hnum);
  862.  }
  863.  return(FALSE);
  864. }
  865.  
  866. /* Close a (partially open)
  867.  * picture, clearing everything
  868.  * down in reverse order
  869.  */
  870. void
  871. CloseAPicture(struct Picture *pic) {
  872.     int i;    // Loop counter for bitmaps
  873.     if (pic) {
  874.         if (pic->Win) {
  875.             ClearMenuStrip(pic->Win);
  876.             CloseWindowSafely(pic->Win);
  877.             pic->Win = NULL;
  878.         }
  879.         if (pic->filename) {
  880.             FreeVec(pic->filename);
  881.             pic->filename = NULL;
  882.         }
  883.         if (pic->Dgad) {
  884.             DisposeObject(pic->Dgad);
  885.             pic->Dgad = NULL;
  886.         }
  887.         if (pic->Ugad) {
  888.             DisposeObject(pic->Ugad);
  889.             pic->Ugad = NULL;
  890.         }
  891.         if (pic->Rgad) {
  892.             DisposeObject(pic->Rgad);
  893.             pic->Rgad = NULL;
  894.         }
  895.         if (pic->Lgad) {
  896.             DisposeObject(pic->Lgad);
  897.             pic->Lgad = NULL;
  898.         }
  899.         if (pic->Uimage) {
  900.             DisposeObject(pic->Uimage);
  901.             pic->Uimage = NULL;
  902.         }
  903.         if (pic->Dimage) {
  904.             DisposeObject(pic->Dimage);
  905.             pic->Dimage = NULL;
  906.         }
  907.         if (pic->Rimage) {
  908.             DisposeObject(pic->Rimage);
  909.             pic->Rimage = NULL;
  910.         }
  911.         if (pic->Limage) {
  912.             DisposeObject(pic->Limage);
  913.             pic->Limage = NULL;
  914.         }
  915.         if (pic->SideGad) {
  916.             DisposeObject(pic->SideGad);
  917.             pic->SideGad = NULL;
  918.         }
  919.         if (pic->BotGad) {
  920.             DisposeObject(pic->BotGad);
  921.             pic->BotGad = NULL;
  922.         }
  923.         if (ZoomAllowed) {
  924.             for (i=0;
  925.                 (i < pic->ilbm->Bmhd.nPlanes) && (i < 8);
  926.                 ++i) {
  927.                 if (pic->BitMap.Planes[i]) {
  928.                     FreeRaster(pic->BitMap.Planes[i],pic->ilbm->Bmhd.w<<1,pic->ilbm->Bmhd.h<<1);
  929.                     pic->BitMap.Planes[i] = NULL;
  930.                 }
  931.             }
  932.         }
  933.         if (pic->ilbm) {
  934.             unloadbrush(pic->ilbm);
  935.             if (pic->ilbm->ParseInfo.iff) {
  936.                 FreeIFF(pic->ilbm->ParseInfo.iff);
  937.             }
  938.             FreeMem(pic->ilbm,sizeof(struct ILBMInfo));
  939.             pic->ilbm = NULL;
  940.         }
  941.         if (pic->Screen) {
  942.             if (pic->DRI) {
  943.                 FreeScreenDrawInfo(pic->Screen,pic->DRI);
  944.                 pic->DRI = NULL;
  945.             }
  946.             UnlockPubScreen(NULL,pic->Screen);
  947.             pic->Screen = NULL;
  948.         }
  949.     }
  950. }
  951.  
  952. /* After opening or resizing a window
  953.  * this does various gadget recalculations
  954.  */
  955. void
  956. doNewSize(struct Picture *pic) {
  957.     ULONG tmp;
  958.     /* If window made wider then may need to scroll image
  959.      * right to prevent gap on the right
  960.      */
  961.     tmp = pic->Win->RPort->Layer->Scroll_X + pic->Win->GZZWidth;
  962.     if (tmp >= (pic->ilbm->Bmhd.w<<Zoom)) {
  963.         ScrollLayer(0,pic->Win->RPort->Layer,(pic->ilbm->Bmhd.w<<Zoom)-tmp,0);
  964.         pic->Left += (pic->ilbm->Bmhd.w<<Zoom)-tmp;
  965.     }
  966.     /* Update sideways gadget and recalculate movement */
  967.     SetGadgetAttrs(pic->BotGad, pic->Win, NULL,
  968.         PGA_Visible, pic->Win->GZZWidth,
  969.         PGA_Top, pic->Left, TAG_END);
  970.     pic->ALeft = pic->Win->GZZWidth/10;
  971.     pic->MLeft = (pic->ilbm->Bmhd.w<<Zoom) - pic->Win->GZZWidth;
  972.     /* If window made taller then may need to scroll image
  973.      * down to prevent gap at the bottom
  974.      */
  975.     tmp = pic->Win->RPort->Layer->Scroll_Y + pic->Win->GZZHeight;
  976.     if (tmp >= (pic->ilbm->Bmhd.h<<Zoom)) {
  977.         ScrollLayer(0,pic->Win->RPort->Layer,0,(pic->ilbm->Bmhd.h<<Zoom)-tmp);
  978.         pic->Top += (pic->ilbm->Bmhd.h<<Zoom)-tmp;
  979.     }
  980.     /* Update vertical gadget and recalculate movement */
  981.     SetGadgetAttrs(pic->SideGad, pic->Win, NULL,
  982.         PGA_Visible, pic->Win->GZZHeight,
  983.         PGA_Top, pic->Top, TAG_END);
  984.     pic->ATop = pic->Win->GZZHeight/10;
  985.     pic->MTop = (pic->ilbm->Bmhd.h<<Zoom) - pic->Win->GZZHeight;
  986. }
  987.  
  988. /* Scroll the image when required */
  989. void
  990. checkGadget(struct Picture *pic) {
  991.     WORD dX;
  992.     WORD dY;
  993.     dY = pic->Top-pic->XTop;
  994.     dX = pic->Left-pic->XLeft;
  995.     if (dX || dY) {
  996.         ScrollLayer(0,pic->Win->RPort->Layer,dX,dY);
  997.     }
  998. }
  999.  
  1000. /* Draw a point and linked lines if required
  1001.  * if MyPoint is not supplied the just draw the point
  1002.  */
  1003. VOID
  1004. DrawPixels(struct Picture *pic,SHORT x,SHORT y,struct MyPoint *MyPoint) {
  1005.     SHORT zx,zy;
  1006.     /* Scale coordinates if zoomed
  1007.      * and draw 3x3 point
  1008.      */
  1009.     zx = x << Zoom;
  1010.     zy = y << Zoom;
  1011.     WritePixel(pic->Win->RPort,zx-2,zy-2);
  1012.     WritePixel(pic->Win->RPort,zx-1,zy-2);
  1013.     WritePixel(pic->Win->RPort,zx,zy-2);
  1014.     WritePixel(pic->Win->RPort,zx+1,zy-2);
  1015.     WritePixel(pic->Win->RPort,zx+2,zy-2);
  1016.     WritePixel(pic->Win->RPort,zx-2,zy-1);
  1017.     WritePixel(pic->Win->RPort,zx-1,zy-1);
  1018.     WritePixel(pic->Win->RPort,zx,zy-1);
  1019.     WritePixel(pic->Win->RPort,zx+1,zy-1);
  1020.     WritePixel(pic->Win->RPort,zx+2,zy-1);
  1021.     WritePixel(pic->Win->RPort,zx-2,zy);
  1022.     WritePixel(pic->Win->RPort,zx-1,zy);
  1023.     WritePixel(pic->Win->RPort,zx,zy);
  1024.     WritePixel(pic->Win->RPort,zx+1,zy);
  1025.     WritePixel(pic->Win->RPort,zx+2,zy);
  1026.     WritePixel(pic->Win->RPort,zx-2,zy+1);
  1027.     WritePixel(pic->Win->RPort,zx-1,zy+1);
  1028.     WritePixel(pic->Win->RPort,zx,zy+1);
  1029.     WritePixel(pic->Win->RPort,zx+1,zy+1);
  1030.     WritePixel(pic->Win->RPort,zx+2,zy+1);
  1031.     WritePixel(pic->Win->RPort,zx-2,zy+2);
  1032.     WritePixel(pic->Win->RPort,zx-1,zy+2);
  1033.     WritePixel(pic->Win->RPort,zx,zy+2);
  1034.     WritePixel(pic->Win->RPort,zx+1,zy+2);
  1035.     WritePixel(pic->Win->RPort,zx+2,zy+2);
  1036.     /* Draw linked lines in the correct window if MyPoint supplied
  1037.      * Note: MyDraw is like Draw only it always draws top left to bottom right
  1038.      *         to prevent problems when erasing lines in the other direction
  1039.      */
  1040.     if (pic == &Pic2) {
  1041.         if (MyPoint) {
  1042.             if (MyPoint->p1) {
  1043.                 MyDraw(pic->Win->RPort,MyPoint->p1->x1<<Zoom,MyPoint->p1->y1<<Zoom,zx,zy);
  1044.             }    
  1045.             if (MyPoint->p2) {
  1046.                 MyDraw(pic->Win->RPort,MyPoint->p2->x1<<Zoom,MyPoint->p2->y1<<Zoom,zx,zy);
  1047.             }
  1048.             if (MyPoint->p3) {
  1049.                 MyDraw(pic->Win->RPort,MyPoint->p3->x1<<Zoom,MyPoint->p3->y1<<Zoom,zx,zy);
  1050.             }
  1051.             if (MyPoint->p4) {
  1052.                 MyDraw(pic->Win->RPort,MyPoint->p4->x1<<Zoom,MyPoint->p4->y1<<Zoom,zx,zy);
  1053.             }
  1054.         }
  1055.     }
  1056.     else {
  1057.         if (MyPoint) {
  1058.             if (MyPoint->p1) {
  1059.                 MyDraw(pic->Win->RPort,MyPoint->p1->x<<Zoom,MyPoint->p1->y<<Zoom,zx,zy);
  1060.             }
  1061.             if (MyPoint->p2) {
  1062.                 MyDraw(pic->Win->RPort,MyPoint->p2->x<<Zoom,MyPoint->p2->y<<Zoom,zx,zy);
  1063.             }
  1064.             if (MyPoint->p3) {
  1065.                 MyDraw(pic->Win->RPort,MyPoint->p3->x<<Zoom,MyPoint->p3->y<<Zoom,zx,zy);
  1066.             }
  1067.             if (MyPoint->p4) {
  1068.                 MyDraw(pic->Win->RPort,MyPoint->p4->x<<Zoom,MyPoint->p4->y<<Zoom,zx,zy);
  1069.             }
  1070.         }
  1071.     }
  1072. }    
  1073.  
  1074. /* Delete all points
  1075.  * Erasing them if images are open
  1076.  */
  1077. void
  1078. DeleteAllPoints(void) {
  1079.     struct MyPoint *MyPoint;
  1080.     /* Loop round looking at the first point every time
  1081.      * since DeletePoint removes it from the list
  1082.      */
  1083.     while ((MyPoint = (struct MyPoint *)PointList.lh_Head)->MyNode.mln_Succ) {
  1084.         if (Pic1_Open) {
  1085.             DrawPixels(&Pic1,MyPoint->x,MyPoint->y,MyPoint);
  1086.         }
  1087.         if (Pic2_Open) {
  1088.             DrawPixels(&Pic2,MyPoint->x1,MyPoint->y1,MyPoint);
  1089.         }
  1090.         DeletePoint(MyPoint);
  1091.     }
  1092. }
  1093.  
  1094. /* Open a project
  1095.  * Suggests you save first if not already saved
  1096.  * Returns        : TRUE or FALSE for how well it went
  1097.  * filename        : file name to open - if NULL then display ASL file requeseter
  1098.  * JustPoints    : If TRUE then only the points are used
  1099.  * Gui         : Display error messages
  1100.  */
  1101. BOOL
  1102. MyOpen(char *filename,BOOL JustPoints,BOOL Gui) {
  1103.     LONG PointCount    = 0;        // Number of points read
  1104.     LONG i;                            // General loop counter
  1105.     char *ifilename    = NULL;    // File name to use
  1106.     BOOL ok                = TRUE;    // Is it all working?
  1107.     BPTR fh;                            // File handle
  1108.     char buffer[257];                // Buffer to read records
  1109.     LONG w=0,h=0;                    // Width and Height
  1110.     LONG x,x1,y,y1;                // Coordinates in image 1 and 2
  1111.     LONG p1,p2;                        // Index to linked points
  1112.     LONG Frames;                    // Number of frames
  1113.     struct MyPoint *MyPoint,    // Points to create and link
  1114.                         *MyPoint1;
  1115.     BOOL JP = FALSE;                // Set if 2.0 points file
  1116.     /* If current project not saved then suggest it is saved    */
  1117.     if (!Saved) {
  1118.         if (!SaveRequester()) {
  1119.             return ok;
  1120.         }
  1121.         DisableWindows(DI_WaitOpen);
  1122.     }
  1123.     /* Get filename, from parameter or ASL requester, save name for saving later */
  1124.     if (filename) {
  1125.         ifilename = filename;
  1126.         if (!JustPoints) {
  1127.             strncpy(savedfilename,filename,256);
  1128.         }
  1129.     }
  1130.     else {
  1131.         if (GetAFile(*savedfilename?savedfilename:"",
  1132.                          (Tag) JustPoints ? "TSMorph - Load Points": "TSMorph - Load Project",
  1133.                          0)) {
  1134.             ifilename=TempFilename;
  1135.             if (!JustPoints) {
  1136.                 strncpy(savedfilename,TempFilename,256);
  1137.             }
  1138.         }
  1139.       }
  1140.       /* If we have a filename then delete current points and set the window title    */
  1141.     if (ifilename) {
  1142.         if (!JustPoints) {
  1143.             OpenNewArgs(ifilename);        // Load new parameters
  1144.             InitParams(FALSE);
  1145.         }
  1146.         DeleteAllPoints();
  1147.         SetWindowTitles(TSMorphWnd,(UBYTE *)-1,savedfilename);
  1148.         if (fh=Open(ifilename,MODE_OLDFILE)) {
  1149.             // Get header
  1150.             FGets(fh,buffer,256);
  1151.             if (JustPoints && (JP = !strcmp(buffer,"TSMorph 2.0\n"))) {
  1152.                 DeleteAllPoints();
  1153.             }
  1154.             else {
  1155.                 if (strcmp(buffer,"TSMorph 1.2\n")) {
  1156.                     Error("Assuming version 1.0 file format","OK",NULL,HE_OldFormat);
  1157.                 }
  1158.                 else {
  1159.                     // Name of first image
  1160.                     FGets(fh,buffer,256);
  1161.                 }
  1162.             }
  1163.             if (!JustPoints) {
  1164.                 if (strlen(buffer)) {
  1165.                     buffer[strlen(buffer)-1]=0;
  1166.                 }
  1167.                 GT_SetGadgetAttrs(TSMorphGadgets[GDX_FileOne],TSMorphWnd,NULL,
  1168.                                         GTST_String, buffer, TAG_END );
  1169.             }
  1170.             // Name of second image
  1171.             if (!JP) {
  1172.                 FGets(fh,buffer,256);
  1173.                 if (!JustPoints) {
  1174.                     if (strlen(buffer)) {
  1175.                         buffer[strlen(buffer)-1]=0;
  1176.                     }
  1177.                     GT_SetGadgetAttrs(TSMorphGadgets[GDX_FileTwo],TSMorphWnd,NULL,
  1178.                                             GTST_String, buffer, TAG_END );
  1179.                 }
  1180.                 // 24 bit name of first image
  1181.                 FGets(fh,buffer,256);
  1182.                 if (!JustPoints) {
  1183.                     if (strlen(buffer)) {
  1184.                         buffer[strlen(buffer)-1]=0;
  1185.                     }
  1186.                     GT_SetGadgetAttrs(TSMorphGadgets[GDX_File241],TSMorphWnd,NULL,
  1187.                                             GTST_String, buffer, TAG_END );
  1188.                 }
  1189.                 // 24 bit name of second image
  1190.                 FGets(fh,buffer,256);
  1191.                 if (!JustPoints) {
  1192.                     if (strlen(buffer)) {
  1193.                         buffer[strlen(buffer)-1]=0;
  1194.                     }
  1195.                     GT_SetGadgetAttrs(TSMorphGadgets[GDX_File242],TSMorphWnd,NULL,
  1196.                                             GTST_String, buffer, TAG_END );
  1197.                 }
  1198.                 // Name of animation
  1199.                 FGets(fh,buffer,256);
  1200.                 if (!JustPoints) {
  1201.                     if (strlen(buffer)) {
  1202.                         buffer[strlen(buffer)-1]=0;
  1203.                     }
  1204.                     GT_SetGadgetAttrs(TSMorphGadgets[GDX_Name],TSMorphWnd,NULL,
  1205.                                             GTST_String, buffer, TAG_END );
  1206.                 }
  1207.                 // General stuff
  1208.                 FGets(fh,buffer,256);
  1209.                 if (!JustPoints) {
  1210.                     if (ok && (sscanf(buffer,"w=%ld,h=%ld,Frames=%ld,Single=%ld,Start=%ld",&w,&h,&Frames,&SinglePicture,&Start) != 5)) {
  1211.                         Error("Invalid file format\nLine '%s'","OK",buffer,HE_FileFormat);
  1212.                         ok = FALSE;
  1213.                     }
  1214.                     else {
  1215.                         GT_SetGadgetAttrs(TSMorphGadgets[GDX_Frames],TSMorphWnd,NULL,
  1216.                                                 GTIN_Number,Frames, TAG_END );
  1217.                         GT_SetGadgetAttrs(TSMorphGadgets[GDX_Start],TSMorphWnd,NULL,
  1218.                                                     GTIN_Number,Start, TAG_END );
  1219.                         GT_SetGadgetAttrs(TSMorphGadgets[GDX_SinglePicture],TSMorphWnd,NULL,
  1220.                                                 GTCY_Active,SinglePicture, TAG_END );
  1221.                         if (ok && ControlWindow &&
  1222.                                 ((w > Pic1.ilbm->Bmhd.w) ||
  1223.                              (h > Pic1.ilbm->Bmhd.h))) {
  1224.                             Error("Images are too small","OK",NULL,HE_TooSmall);
  1225.                             ok = FALSE;
  1226.                         }
  1227.                     }
  1228.                 }
  1229.             }
  1230.             if (ok) {
  1231.                 MaxWidth     = 0;
  1232.                 MaxHeight     = 0;
  1233.                 // Read and validate point
  1234.                 while (ok &&
  1235.                     FGets(fh,buffer,256) &&
  1236.                     (sscanf(buffer,"x=%ld,y=%ld,x1=%ld,y1=%ld",&x,&y,&x1,&y1) == 4)) {
  1237.                     if (Pic1_Open) {
  1238.                         if ((x<0)||(x>(Pic1.ilbm->Bmhd.w-1)) ||
  1239.                              (y<0)||(y>(Pic1.ilbm->Bmhd.h-1))) {
  1240.                             Error("Point out of range\nLine '%s'","OK",buffer,HE_Range);
  1241.                             ok = FALSE;
  1242.                         }
  1243.                     }
  1244.                     // Create point and add to list
  1245.                     if (MyPoint = AllocMem(sizeof(struct MyPoint),MEMF_CLEAR)) {
  1246.                         MyPoint->x = x;
  1247.                         MyPoint->y = y;
  1248.                         MyPoint->x1 = x1;
  1249.                         MyPoint->y1 = y1;
  1250.                         MaxWidth = max(x,MaxWidth);
  1251.                         MaxWidth = max(x1,MaxWidth);
  1252.                         MaxHeight = max(y,MaxHeight);
  1253.                         MaxHeight = max(y1,MaxHeight);
  1254.                         AddTail(&PointList,(struct Node *)MyPoint);
  1255.                         ++PointCount;
  1256.                         if (ControlWindow) {
  1257.                             // If the windows are open then actually draw the points
  1258.                             DrawPixels(&Pic1,x,y,MyPoint);
  1259.                             DrawPixels(&Pic2,x1,y1,MyPoint);
  1260.                         }
  1261.                     }
  1262.                     else {
  1263.                         Error("Out of memory for points","OK",NULL,HE_MemPoints);
  1264.                         ok=FALSE;
  1265.                     }
  1266.                 }
  1267.                 Width = max(w,MaxWidth);
  1268.                 Height = max(h,MaxHeight);
  1269.                 if (Pic1_Open) {
  1270.                     Width = max(Width,Pic1.ilbm->Bmhd.w);
  1271.                     Height = max(Height,Pic1.ilbm->Bmhd.h);
  1272.                 }
  1273.                 GT_SetGadgetAttrs(TSMorphGadgets[GDX_Width],TSMorphWnd,NULL,
  1274.                                         GTNM_Number,Width, TAG_END );
  1275.                 GT_SetGadgetAttrs(TSMorphGadgets[GDX_Height],TSMorphWnd,NULL,
  1276.                                         GTNM_Number,Height, TAG_END );
  1277.                 // Read all the links
  1278.                 while (ok &&
  1279.                     (sscanf(buffer,"p1=%ld,p2=%ld",&p1,&p2) == 2)) {
  1280.                     if ((p1>PointCount) || (p2>PointCount)) {
  1281.                         Error("Invalid point link\nLine '%s'","OK",buffer,HE_InvLink);
  1282.                         ok = FALSE;
  1283.                     }
  1284.                     else {
  1285.                         // Link two points based on indexes to linked lists
  1286.                         i = 0;
  1287.                         MyPoint = (struct MyPoint *)PointList.lh_Head;
  1288.                         while (i < p1) {
  1289.                             MyPoint = (struct MyPoint *)MyPoint->MyNode.mln_Succ;
  1290.                             ++i;
  1291.                         }
  1292.                         i = 0;
  1293.                         MyPoint1 = (struct MyPoint *)PointList.lh_Head;
  1294.                         while (i < p2) {
  1295.                             MyPoint1 = (struct MyPoint *)MyPoint1->MyNode.mln_Succ;
  1296.                             ++i;
  1297.                         }
  1298.                         LinkPoints(MyPoint,MyPoint1);
  1299.                     }
  1300.                     if (!FGets(fh,buffer,256)) {
  1301.                         ok = FALSE;
  1302.                     }
  1303.                 }
  1304.             }
  1305.             // Close file and return cleanly
  1306.             if (!Close(fh)) {
  1307.                 if (ok) {
  1308.                     Error("Error closing file '%s'","OK",ifilename,HE_Close);
  1309.                     ok = FALSE;
  1310.                 }
  1311.             }
  1312.         }
  1313.         else {
  1314.             if (Gui) {
  1315.                 Error("Error opening file '%s'","OK",ifilename,HE_Open);
  1316.             }
  1317.             ok = FALSE;
  1318.         }
  1319.     }
  1320.     if (ok && !JustPoints) {
  1321.         Saved = TRUE;
  1322.     }
  1323.     else {
  1324.         if (ok && JustPoints) {
  1325.             Saved = FALSE;
  1326.         }
  1327.     }
  1328.     return ok;
  1329. }
  1330.  
  1331. /* Saves a project
  1332.  * Returns        : TRUE or FALSE for how well it went
  1333.  * filename        : file name to open - if NULL then display ASL file requeseter
  1334.  */
  1335. BOOL
  1336. SaveAs(char *filename) {
  1337.     char buffer[257];                // buffer to write records
  1338.     char *ifilename    = NULL;    // File name to use
  1339.     BPTR fh;                            // File handle
  1340.     LONG i,                            // Loop counters
  1341.           j;
  1342.     BOOL ok;                            // How well is it going
  1343.     struct MyPoint *MyPoint,    // Points to write
  1344.                         *MyPoint1;
  1345.     struct DiskObject *MyDiskObject;    // The Icon
  1346.     /* Set up the file name from the parameter or using and ASL requester    */
  1347.     if (filename && *filename) {
  1348.         ifilename = filename;
  1349.         strncpy(savedfilename,filename,256);
  1350.     }
  1351.     else {
  1352.         if (GetAFile(*savedfilename?savedfilename:"","TSMorph - Save Project",FILF_SAVE)) {
  1353.             ifilename=TempFilename;
  1354.             strncpy(savedfilename,TempFilename,256);
  1355.         }
  1356.       }
  1357.       /* If we have a file name then set the window title
  1358.        * and write out the fixed information
  1359.        */
  1360.     if (ifilename) {
  1361.         SetWindowTitles(TSMorphWnd,(UBYTE *)-1,savedfilename);
  1362.         if (fh=Open(ifilename,MODE_NEWFILE)) {
  1363.             FPuts(fh,"TSMorph 1.2\n");
  1364.             FPuts(fh,GetString(TSMorphGadgets[GDX_FileOne]));
  1365.             FPuts(fh,"\n");
  1366.             FPuts(fh,GetString(TSMorphGadgets[GDX_FileTwo]));
  1367.             FPuts(fh,"\n");
  1368.             FPuts(fh,GetString(TSMorphGadgets[GDX_File241]));
  1369.             FPuts(fh,"\n");
  1370.             if ((SinglePicture == 0) || (SinglePicture == 2)) {
  1371.                 FPuts(fh,GetString(TSMorphGadgets[GDX_File242]));
  1372.             }
  1373.             FPuts(fh,"\n");
  1374.             FPuts(fh,GetString(TSMorphGadgets[GDX_Name]));
  1375.             FPuts(fh,"\n");
  1376.             sprintf(buffer,"w=%ld,h=%ld,Frames=%ld,Single=%ld,Start=%ld\n",
  1377.                     Width,Height,GetNumber(TSMorphGadgets[GDX_Frames]),SinglePicture,GetNumber(TSMorphGadgets[GDX_Start]));
  1378.             ok = !FPuts(fh,buffer);
  1379.             if ((SinglePicture == 2) || (SinglePicture == 3)) {
  1380.                 if (ControlWindow) {
  1381.                     if (!Close(fh)) {
  1382.                         if (ok) {
  1383.                             Error("Error closing file '%s'","OK",ifilename,HE_Close);
  1384.                             ok = FALSE;
  1385.                         }
  1386.                     }
  1387.                     strcpy(buffer,ifilename);
  1388.                     strcat(buffer,".%03ld");
  1389.                     sprintf(TempFilename,buffer,FrameNumber);
  1390.                     ifilename = TempFilename;
  1391.                     if (fh=Open(ifilename,MODE_NEWFILE)) {
  1392.                         FPuts(fh,"TSMorph 2.0\n");
  1393.                     }
  1394.                     else {
  1395.                         Error("Error opening file '%s'","OK",ifilename,HE_Open);
  1396.                         ok = FALSE;
  1397.                     }
  1398.                 }
  1399.             }
  1400.             // Write out all the points
  1401.             for (MyPoint = (struct MyPoint *)PointList.lh_Head;
  1402.                     MyPoint->MyNode.mln_Succ && ok;
  1403.                     MyPoint = (struct MyPoint *)MyPoint->MyNode.mln_Succ) {
  1404.                 sprintf(buffer,"x=%ld,y=%ld,x1=%ld,y1=%ld\n",MyPoint->x,MyPoint->y,MyPoint->x1,MyPoint->y1);
  1405.                 ok = !FPuts(fh,buffer);
  1406.             }
  1407.             // Write out all the links
  1408.             i = 0;
  1409.             for (MyPoint = (struct MyPoint *)PointList.lh_Head;
  1410.                     MyPoint->MyNode.mln_Succ && ok;
  1411.                     MyPoint = (struct MyPoint *)MyPoint->MyNode.mln_Succ) {
  1412.                 j = 0;
  1413.                 for (MyPoint1= (struct MyPoint *)PointList.lh_Head;
  1414.                         MyPoint1->MyNode.mln_Succ;
  1415.                         MyPoint1 = (struct MyPoint *)MyPoint1->MyNode.mln_Succ) {
  1416.                     // Only write each link once
  1417.                     if (j>i) {
  1418.                         if ((MyPoint->p1 == MyPoint1) ||
  1419.                              (MyPoint->p2 == MyPoint1) ||
  1420.                              (MyPoint->p3 == MyPoint1) ||
  1421.                              (MyPoint->p4 == MyPoint1)) {
  1422.                             sprintf(buffer,"p1=%ld,p2=%ld\n",i,j);
  1423.                             ok = !FPuts(fh,buffer);
  1424.                         }
  1425.                     }
  1426.                     ++j;
  1427.                 }
  1428.                 ++i;
  1429.             }
  1430.             if (!ok) {
  1431.                 Error("Error writing to '%s'","OK",ifilename,HE_Write);
  1432.             }
  1433.             // Close file and clean up
  1434.             if (!Close(fh)) {
  1435.                 if (ok) {
  1436.                     Error("Error closing file '%s'","OK",ifilename,HE_Close);
  1437.                     ok = FALSE;
  1438.                 }
  1439.             }
  1440.         }
  1441.         else {
  1442.             Error("Error opening file '%s'","OK",ifilename,HE_Open);
  1443.             ok = FALSE;
  1444.         }
  1445.         // Write Icon if required and none already exists
  1446.         if (ok) {
  1447.             if (CreateIcons) {
  1448.                 if (MyDiskObject = GetDiskObject(savedfilename)) {
  1449.                     FreeDiskObject(MyDiskObject);
  1450.                 }
  1451.                 else {
  1452.                     if ((MyDiskObject = GetDiskObject("ENV:TSMorph/def_points")) ||
  1453.                         (MyDiskObject = GetDiskObject("ENV:SYS/def_points")) ||
  1454.                          (MyDiskObject = GetDefDiskObject(WBPROJECT))) {
  1455.                         PutDiskObject(savedfilename,MyDiskObject);
  1456.                         FreeDiskObject(MyDiskObject);
  1457.                     }
  1458.                 }
  1459.             }
  1460.             Saved = TRUE;
  1461.         }
  1462.     }
  1463.     else {
  1464.         ok = FALSE;
  1465.     }
  1466.     return ok;
  1467. }
  1468.  
  1469. /* Set editing mode
  1470.  * This sets the window title, pointer, gadgets, menus etc.
  1471.  */
  1472. void
  1473. MySetMode(UWORD NewMode) {
  1474.     UWORD             oldpos;                // Pointer to unlink gadgets
  1475.     UWORD             menupos;                // menu pointer
  1476.     struct Gadget     *Gadget1    = NULL;    // Gadget to update
  1477.     ULONG                HNum;
  1478.     // Determine "current" menu and gadget
  1479.     switch(Mode) {
  1480.     case EDIT1:
  1481.         Gadget1 = &OneGadget;
  1482.         menupos = MI_EDITONE;
  1483.         break;
  1484.     case EDIT2:
  1485.         Gadget1 = &TwoGadget;
  1486.         menupos = MI_EDITTWO;
  1487.         break;
  1488.     case EDITREL:
  1489.          Gadget1 = &RelGadget;
  1490.         menupos = MI_EDITREL;
  1491.          break;
  1492.     case ADD:
  1493.         Gadget1 = &MyAddGadget;
  1494.         menupos = MI_ADD;
  1495.         break;
  1496.     case DELETE:
  1497.         Gadget1 = &DelGadget;
  1498.         menupos = MI_DELETE;
  1499.         break;
  1500.     case LINK1:
  1501.     case LINK2:
  1502.     case LINK2A:
  1503.         Gadget1 = &LinkGadget;
  1504.         menupos = MI_LINK;
  1505.         break;
  1506.     case UNLINK1:
  1507.     case UNLINK2:
  1508.     case UNLINK2A:
  1509.         Gadget1 = &UnlinkGadget;
  1510.         menupos = MI_UNLINK;
  1511.         break;
  1512.     case NONE:
  1513.         Gadget1 = &NoneGadget;
  1514.         menupos = MI_NONE;
  1515.         break;
  1516.     }
  1517.     // Unselect old gadget
  1518.     oldpos = RemoveGList(ControlWindow,Gadget1,1);
  1519.     Gadget1->Flags &= ~GFLG_SELECTED;
  1520.     AddGList(ControlWindow,Gadget1,oldpos,1,NULL);
  1521.     RefreshGList(Gadget1,ControlWindow,NULL,1);
  1522.     /* Remove menus and
  1523.      * Unselect old menu item
  1524.      * Actually unselects all (why?)
  1525.      */
  1526.     ClearMenuStrip(Pic1.Win);
  1527.     ClearMenuStrip(Pic2.Win);
  1528.     ClearMenuStrip(ControlWindow);
  1529.     (ItemAddress(MyMenu,FULLMENUNUM(M_EDIT,MM_MODE,0)))->Flags &= ~CHECKED;
  1530.     (ItemAddress(MyMenu,FULLMENUNUM(M_EDIT,MM_MODE,1)))->Flags &= ~CHECKED;
  1531.     (ItemAddress(MyMenu,FULLMENUNUM(M_EDIT,MM_MODE,2)))->Flags &= ~CHECKED;
  1532.     (ItemAddress(MyMenu,FULLMENUNUM(M_EDIT,MM_MODE,3)))->Flags &= ~CHECKED;
  1533.     (ItemAddress(MyMenu,FULLMENUNUM(M_EDIT,MM_MODE,4)))->Flags &= ~CHECKED;
  1534.     (ItemAddress(MyMenu,FULLMENUNUM(M_EDIT,MM_MODE,5)))->Flags &= ~CHECKED;
  1535.     (ItemAddress(MyMenu,FULLMENUNUM(M_EDIT,MM_MODE,6)))->Flags &= ~CHECKED;
  1536.     (ItemAddress(MyMenu,FULLMENUNUM(M_EDIT,MM_MODE,7)))->Flags &= ~CHECKED;
  1537.     // Determine "new" title, gadget and menu
  1538.     switch (NewMode) {
  1539.     case EDIT1:
  1540.         SetWindowTitles(ControlWindow,"1",(UBYTE *)-1);
  1541.         Gadget1 = &OneGadget;
  1542.         menupos = MI_EDITONE;
  1543.         HNum = H_EOne;
  1544.         break;
  1545.     case EDIT2:
  1546.         SetWindowTitles(ControlWindow,"2",(UBYTE *)-1);
  1547.         Gadget1 = &TwoGadget;
  1548.         menupos = MI_EDITTWO;
  1549.         HNum = H_ETwo;
  1550.         break;
  1551.     case EDITREL:
  1552.         SetWindowTitles(ControlWindow,"Rel",(UBYTE *)-1);
  1553.          Gadget1 = &RelGadget;
  1554.         menupos = MI_EDITREL;
  1555.         HNum = H_ERel;
  1556.         break;
  1557.     case ADD:
  1558.         SetWindowTitles(ControlWindow,"Add",(UBYTE *)-1);
  1559.           Gadget1 = &MyAddGadget;
  1560.         menupos = MI_ADD;
  1561.         HNum = H_EAdd;
  1562.         break;
  1563.     case DELETE:
  1564.         SetWindowTitles(ControlWindow,"Del",(UBYTE *)-1);
  1565.           Gadget1 = &DelGadget;
  1566.         menupos = MI_DELETE;
  1567.         HNum = H_EDel;
  1568.         break;
  1569.     case LINK1:
  1570.         SetWindowTitles(ControlWindow,"L1",(UBYTE *)-1);
  1571.           Gadget1 = &LinkGadget;
  1572.         menupos = MI_LINK;
  1573.         HNum = H_ELnk;
  1574.         break;
  1575.     case UNLINK1:
  1576.         SetWindowTitles(ControlWindow,"U1",(UBYTE *)-1);
  1577.           Gadget1 = &UnlinkGadget;
  1578.         menupos = MI_UNLINK;
  1579.         HNum = H_EUnl;
  1580.         break;
  1581.     case NONE:
  1582.         SetWindowTitles(ControlWindow,"Mov",(UBYTE *)-1);
  1583.          Gadget1 = &NoneGadget;
  1584.         menupos = MI_NONE;
  1585.         HNum = H_EMov;
  1586.         break;
  1587.     }
  1588.     // Select new gadget
  1589.     oldpos = RemoveGList(ControlWindow,Gadget1,1);
  1590.     Gadget1->Flags |= GFLG_SELECTED;
  1591.     AddGList(ControlWindow,Gadget1,oldpos,1,NULL);
  1592.     RefreshGList(Gadget1,ControlWindow,NULL,1);
  1593.     // Select new menu item and readd menus
  1594.     (ItemAddress(MyMenu,FULLMENUNUM(M_EDIT,MM_MODE,menupos)))->Flags |= CHECKED;
  1595.     ResetMenuStrip(ControlWindow,MyMenu);
  1596.     ResetMenuStrip(Pic1.Win,MyMenu);
  1597.     ResetMenuStrip(Pic2.Win,MyMenu);
  1598.     // Set mode and set the pointer
  1599.     Mode = NewMode;
  1600.     SetMyPointer();
  1601.     // Display (short) help
  1602.     if (GHelp) {
  1603.         help(HNum);
  1604.     }
  1605.     else {
  1606.         ihelp(HNum);
  1607.     }
  1608. }
  1609.  
  1610. /* The main program
  1611.  * this loops until the program is quited
  1612.  */
  1613. void
  1614. doMsgLoop(void) {
  1615.     UWORD                     X,                // Coordinates
  1616.                                 Y;
  1617.     struct IntuiMessage     *msg;            // Message from the Control window
  1618.     struct Picture         *pic;            // Main image pointer
  1619.     struct Picture         *pic1;        // The other image
  1620.     int                         flag     = 1;    // 1 = keep going, 0 = quit, 2 = Close control and image windows
  1621.     UWORD                     Shift;        // Set if either Shift key pressed
  1622.     ULONG                     Signals;        // Signals set after Wait()
  1623.     UWORD                     Selection;    // Menu selection
  1624.     SHORT                     OldX,            // Old coordinates
  1625.                                 OldY;
  1626.     SHORT                     OldX1,        // Old coordinates in other window
  1627.                                 OldY1;
  1628.     SHORT                     CurX,            // Current coordinates
  1629.                                 CurY;
  1630.     SHORT                     CurX1,        // Current coordinates in other window
  1631.                                 CurY1;
  1632.     UWORD                     OldLeft,        // Old position of image
  1633.                                 OldTop;
  1634.     UWORD                     OldLeft1,    // Old position of other image
  1635.                                 OldTop1;
  1636.     BOOL                         SelDown = FALSE;    // Set if left button currently pressed
  1637.     struct MyPoint         *MyPoint,    // Points to add, link etc.
  1638.                                 *MyPoint1;
  1639.     struct AmigaGuideMsg *agm;            // message from amigaguide
  1640.     ULONG HNum;                                // The Help node to use
  1641.     /* Loop until we quit    */
  1642.     while (flag==1) {
  1643.         // Wait on open windows etc.
  1644.         Signals = Wait((ASig) |
  1645.                             (1L << TSMorphWnd->UserPort->mp_SigBit) |
  1646.                             (1L << WMsgPortp->mp_SigBit) |
  1647.                             (ControlWindow ? (1L << ControlWindow->UserPort->mp_SigBit) : 0));
  1648.         // Something for the Information window
  1649.         if (Signals & (1L << TSMorphWnd->UserPort->mp_SigBit)) {
  1650.             flag = HandleTSMorphIDCMP();
  1651.         }
  1652.         /* Something for amigaguide
  1653.          * Note: all we do is reply the message(s)
  1654.          */
  1655.         if (Signals & ASig) {
  1656.             if (handle) {
  1657.                 while (agm = GetAmigaGuideMsg(handle)) {
  1658.                     switch (agm->agm_Type) {
  1659.                     case ToolCmdReplyID:
  1660.                         break;
  1661.                     case ToolStatusID:
  1662.                         break;
  1663.                     default:
  1664.                         break;
  1665.                     }
  1666.                     ReplyAmigaGuideMsg(agm);
  1667.                 }
  1668.             }
  1669.         }
  1670.         // Something for the Control window
  1671.         if (ControlWindow &&
  1672.             (Signals & (1L << ControlWindow->UserPort->mp_SigBit))) {
  1673.             // Loop on all messages
  1674.              while (msg = (struct IntuiMessage *)GetMsg(ControlWindow->UserPort)) {
  1675.                  switch (msg->Class) {
  1676.                  // gadget help
  1677.                  case IDCMP_GADGETHELP:
  1678.                      if (msg->IAddress == NULL) {
  1679.                          HNum = 0;
  1680.                      }
  1681.                      else {
  1682.                          if (msg->IAddress == ControlWindow) {
  1683.                             switch(Mode) {
  1684.                             case EDIT1:
  1685.                                 HNum = H_EOne;
  1686.                                 break;
  1687.                             case EDIT2:
  1688.                                 HNum = H_ETwo;
  1689.                                 break;
  1690.                             case EDITREL:
  1691.                                 HNum = H_ERel;
  1692.                                  break;
  1693.                             case ADD:
  1694.                                 HNum = H_EAdd;
  1695.                                 break;
  1696.                             case DELETE:
  1697.                                 HNum = H_EDel;
  1698.                                 break;
  1699.                             case LINK1:
  1700.                             case LINK2:
  1701.                             case LINK2A:
  1702.                                 HNum = H_ELnk;
  1703.                                 break;
  1704.                             case UNLINK1:
  1705.                             case UNLINK2:
  1706.                             case UNLINK2A:
  1707.                                 HNum = H_EUnl;
  1708.                                 break;
  1709.                             case NONE:
  1710.                                 HNum = H_EMov;
  1711.                                 break;
  1712.                             default:
  1713.                                 HNum = H_CWindow;
  1714.                                 break;
  1715.                             }
  1716.                         }
  1717.                          else {
  1718.                              switch (((struct Gadget *)msg->IAddress)->GadgetType &0xf0) {
  1719.                              case GTYP_WDRAGGING:
  1720.                                  HNum = H_CWindow;
  1721.                                  break;
  1722.                              case GTYP_WUPFRONT:
  1723.                                  HNum = H_CDepth;
  1724.                                  break;
  1725.                              case GTYP_CLOSE:
  1726.                                  HNum = H_CClose;
  1727.                                  break;
  1728.                              case 0:
  1729.                                  switch (((struct Gadget *)msg->IAddress)->GadgetID) {
  1730.                                  case ONEGADGET:
  1731.                                      HNum = H_EOne;
  1732.                                      break;
  1733.                                  case TWOGADGET:
  1734.                                      HNum = H_ETwo;
  1735.                                      break;
  1736.                                  case RELGADGET:
  1737.                                      HNum = H_ERel;
  1738.                                      break;
  1739.                                  case DELGADGET:
  1740.                                      HNum = H_EDel;
  1741.                                      break;
  1742.                                  case UNLINKGADGET:
  1743.                                      HNum = H_EUnl;
  1744.                                      break;
  1745.                                  case LINKGADGET:
  1746.                                      HNum = H_ELnk;
  1747.                                      break;
  1748.                                  case NONEGADGET:
  1749.                                      HNum = H_EMov;
  1750.                                      break;
  1751.                                  case ADDGADGET:
  1752.                                      HNum = H_EAdd;
  1753.                                      break;
  1754.                                  case STGADGET:
  1755.                                      HNum = HC_First;
  1756.                                      break;
  1757.                                  case PREVGADGET:
  1758.                                      HNum = HC_Previous;
  1759.                                      break;
  1760.                                  case GOTOGADGET:
  1761.                                      HNum = HC_Goto;
  1762.                                      break;
  1763.                                  case NEXTGADGET:
  1764.                                      HNum = HC_Next;
  1765.                                      break;
  1766.                                  case LASTGADGET:
  1767.                                      HNum = HC_Last;
  1768.                                      break;
  1769.                                  default:
  1770.                                      HNum = H_CWindow;
  1771.                                      break;
  1772.                                  }
  1773.                                  break;
  1774.                              default:
  1775.                                  HNum = H_CWindow;
  1776.                                  break;
  1777.                              }
  1778.                          }
  1779.                      }
  1780.                      if (HNum) {
  1781.                          if (GHelp) {
  1782.                              help(HNum);
  1783.                          }
  1784.                          else {
  1785.                              ihelp(HNum);
  1786.                          }
  1787.                      }
  1788.                      break;
  1789.                  case IDCMP_VANILLAKEY:
  1790.                      // No vanilla keys currently defined
  1791.                      break;
  1792.                  case IDCMP_RAWKEY:
  1793.                      // only raw key is the help key
  1794.                      switch (msg->Code) {
  1795.                      case 0x5F:
  1796.                          /* determine if pointer is in a gadget
  1797.                           * otherwise show help on the whole window
  1798.                           */
  1799.                         X = ControlWindow->MouseX;
  1800.                         Y = ControlWindow->MouseY;
  1801.                         if (PointInBox(X,Y,0,0,
  1802.                                                 CLOSEIMAGE_W(n),ControlWindow->BorderTop))
  1803.                             HNum = H_CClose;
  1804.                         else
  1805.                         if (PointInBox(X,Y,(ControlWindow->Width - DEPTHIMAGE_W(n)),0,
  1806.                                                 ControlWindow->Width,ControlWindow->BorderTop))
  1807.                             HNum = H_CDepth;
  1808.                         else
  1809.                         if (PointInBox(X,Y,OneGadget.LeftEdge,OneGadget.TopEdge,
  1810.                                                 OneGadget.LeftEdge+OneGadget.Width,OneGadget.TopEdge+OneGadget.Height))
  1811.                             HNum = H_EOne;
  1812.                         else
  1813.                         if (PointInBox(X,Y,TwoGadget.LeftEdge,TwoGadget.TopEdge,
  1814.                                                 TwoGadget.LeftEdge+TwoGadget.Width,TwoGadget.TopEdge+TwoGadget.Height))
  1815.                             HNum = H_ETwo;
  1816.                         else
  1817.                         if (PointInBox(X,Y,RelGadget.LeftEdge,RelGadget.TopEdge,
  1818.                                                 RelGadget.LeftEdge+RelGadget.Width,RelGadget.TopEdge+RelGadget.Height))
  1819.                             HNum = H_ERel;
  1820.                         else
  1821.                         if (PointInBox(X,Y,DelGadget.LeftEdge,DelGadget.TopEdge,
  1822.                                                 DelGadget.LeftEdge+DelGadget.Width,DelGadget.TopEdge+DelGadget.Height))
  1823.                             HNum = H_EDel;
  1824.                         else
  1825.                         if (PointInBox(X,Y,UnlinkGadget.LeftEdge,UnlinkGadget.TopEdge,
  1826.                                                 UnlinkGadget.LeftEdge+UnlinkGadget.Width,UnlinkGadget.TopEdge+UnlinkGadget.Height))
  1827.                             HNum = H_EUnl;
  1828.                         else
  1829.                         if (PointInBox(X,Y,LinkGadget.LeftEdge,LinkGadget.TopEdge,
  1830.                                                 LinkGadget.LeftEdge+LinkGadget.Width,LinkGadget.TopEdge+LinkGadget.Height))
  1831.                             HNum = H_ELnk;
  1832.                         else
  1833.                         if (PointInBox(X,Y,NoneGadget.LeftEdge,NoneGadget.TopEdge,
  1834.                                                 NoneGadget.LeftEdge+NoneGadget.Width,NoneGadget.TopEdge+NoneGadget.Height))
  1835.                             HNum = H_EMov;
  1836.                         else
  1837.                         if (PointInBox(X,Y,MyAddGadget.LeftEdge,MyAddGadget.TopEdge,
  1838.                                                 MyAddGadget.LeftEdge+MyAddGadget.Width,MyAddGadget.TopEdge+MyAddGadget.Height))
  1839.                             HNum = H_EAdd;
  1840.                         else
  1841.                         if (PointInBox(X,Y,stGadget.LeftEdge,stGadget.TopEdge,
  1842.                                                 stGadget.LeftEdge+stGadget.Width,stGadget.TopEdge+stGadget.Height))
  1843.                             HNum = HC_First;
  1844.                         else
  1845.                         if (PointInBox(X,Y,prevGadget.LeftEdge,prevGadget.TopEdge,
  1846.                                                 prevGadget.LeftEdge+prevGadget.Width,prevGadget.TopEdge+prevGadget.Height))
  1847.                             HNum = HC_Previous;
  1848.                         else
  1849.                         if (PointInBox(X,Y,gotoGadget.LeftEdge,gotoGadget.TopEdge,
  1850.                                                 gotoGadget.LeftEdge+gotoGadget.Width,gotoGadget.TopEdge+gotoGadget.Height))
  1851.                             HNum = HC_Goto;
  1852.                         else
  1853.                         if (PointInBox(X,Y,nextGadget.LeftEdge,nextGadget.TopEdge,
  1854.                                                 nextGadget.LeftEdge+nextGadget.Width,nextGadget.TopEdge+nextGadget.Height))
  1855.                             HNum = HC_Next;
  1856.                         else
  1857.                         if (PointInBox(X,Y,lastGadget.LeftEdge,lastGadget.TopEdge,
  1858.                                                 lastGadget.LeftEdge+lastGadget.Width,lastGadget.TopEdge+lastGadget.Height))
  1859.                             HNum = HC_Last;
  1860.                         else
  1861.                             HNum = H_CWindow;
  1862.                         help(HNum);
  1863.                          break;
  1864.                      default:
  1865.                          // any other key
  1866.                          break;
  1867.                      }
  1868.                      break;
  1869.                  case IDCMP_MENUHELP:
  1870.                      // Show help on the Control and image windows menus
  1871.                      DoMenuHelp(msg->Code);
  1872.                      break;
  1873.                  case IDCMP_GADGETDOWN:
  1874.                      // Gadget down so set mode to the gadget pressed
  1875.                      switch (((struct Gadget *)(msg->IAddress))->GadgetID) {
  1876.                     case ONEGADGET:
  1877.                         MySetMode(EDIT1);
  1878.                          break;
  1879.                      case TWOGADGET:
  1880.                          MySetMode(EDIT2);
  1881.                           break;
  1882.                      case RELGADGET:
  1883.                           MySetMode(EDITREL);
  1884.                           break;
  1885.                      case ADDGADGET:
  1886.                          MySetMode(ADD);
  1887.                           break;
  1888.                      case DELGADGET:
  1889.                          MySetMode(DELETE);
  1890.                           break;
  1891.                       case LINKGADGET:
  1892.                           MySetMode(LINK1);
  1893.                           break;
  1894.                      case UNLINKGADGET:
  1895.                          MySetMode(UNLINK1);
  1896.                           break;
  1897.                       case NONEGADGET:
  1898.                           MySetMode(NONE);
  1899.                           break;
  1900.                       default:
  1901.                           // unkown gadget ?
  1902.                           break;
  1903.                      }
  1904.                      break;
  1905.                  case IDCMP_GADGETUP:
  1906.                      // Gadget up so change frame
  1907.                      switch (((struct Gadget *)(msg->IAddress))->GadgetID) {
  1908.                     case STGADGET:
  1909.                         flag = FirstFrame();
  1910.                          break;
  1911.                      case PREVGADGET:
  1912.                          flag = PrevFrame();
  1913.                          break;
  1914.                      case GOTOGADGET:
  1915.                          flag = GotoFrame();
  1916.                          break;
  1917.                      case NEXTGADGET:
  1918.                          flag = NextFrame();
  1919.                          break;
  1920.                      case LASTGADGET:
  1921.                          flag = LastFrame();
  1922.                          break;
  1923.                     default:
  1924.                         break;
  1925.                     }
  1926.                     break;
  1927.                  case IDCMP_CLOSEWINDOW:
  1928.                      // Close window - set flag to close image windows as well
  1929.                     flag = 2;
  1930.                      break;
  1931.                  case IDCMP_MENUPICK:
  1932.                      // Loop around menu selections
  1933.                     Selection = msg->Code;
  1934.                     while ((Selection != MENUNULL) && (flag==1)) {
  1935.                         flag = DoMenu(NULL,Selection);
  1936.                         Selection = ((struct MenuItem *)ItemAddress(MyMenu,(LONG)Selection))->NextSelect;
  1937.                     }
  1938.                      break;
  1939.                  default:
  1940.                      // unknown message
  1941.                      break;
  1942.                  }
  1943.                 ReplyMsg((struct Message *)msg);
  1944.              }
  1945.           }
  1946.           // Something from one of the image windows
  1947.         if (Signals & (1L << WMsgPortp->mp_SigBit)) {
  1948.          // Loop round messages
  1949.          while (msg = (struct IntuiMessage *)GetMsg(WMsgPortp)) {
  1950.              // determine which image it relates to
  1951.             pic = (struct Picture *)(msg->IDCMPWindow->UserData);
  1952.             switch (msg->Class) {
  1953.             case IDCMP_GADGETHELP:
  1954.                  if (msg->IAddress == NULL) {
  1955.                      HNum = 0;
  1956.                  }
  1957.                  else {
  1958.                      if (msg->IAddress == pic->Win) {
  1959.                         switch(Mode) {
  1960.                         case EDIT1:
  1961.                             HNum = H_EOne;
  1962.                             break;
  1963.                         case EDIT2:
  1964.                             HNum = H_ETwo;
  1965.                             break;
  1966.                         case EDITREL:
  1967.                             HNum = H_ERel;
  1968.                              break;
  1969.                         case ADD:
  1970.                             HNum = H_EAdd;
  1971.                             break;
  1972.                         case DELETE:
  1973.                             HNum = H_EDel;
  1974.                             break;
  1975.                         case LINK1:
  1976.                         case LINK2:
  1977.                         case LINK2A:
  1978.                             HNum = H_ELnk;
  1979.                             break;
  1980.                         case UNLINK1:
  1981.                         case UNLINK2:
  1982.                         case UNLINK2A:
  1983.                             HNum = H_EUnl;
  1984.                             break;
  1985.                         case NONE:
  1986.                             HNum = H_EMov;
  1987.                             break;
  1988.                         default:
  1989.                             HNum = H_EWindow;
  1990.                             break;
  1991.                         }
  1992.                      }
  1993.                      else {
  1994.                          switch (((struct Gadget *)msg->IAddress)->GadgetType &0xf0) {
  1995.                          case GTYP_SIZING:
  1996.                              HNum = H_ESize;
  1997.                              break;
  1998.                          case GTYP_WDRAGGING:
  1999.                              HNum = H_EWindow;
  2000.                              break;
  2001.                          case GTYP_WUPFRONT:
  2002.                              HNum = H_EDepth;
  2003.                              break;
  2004.                          case GTYP_WDOWNBACK:
  2005.                              HNum = H_EZoom;
  2006.                              break;
  2007.                          case GTYP_CLOSE:
  2008.                              HNum = H_EClose;
  2009.                              break;
  2010.                          case 0:
  2011.                              switch (((struct Gadget *)msg->IAddress)->GadgetID) {
  2012.                              case LEFT_RIGHT_GADGET:
  2013.                                  HNum = H_Horiz;
  2014.                                  break;
  2015.                              case UP_DOWN_GADGET:
  2016.                                  HNum = H_Vert;
  2017.                                  break;
  2018.                              case UP_GADGET:
  2019.                                  HNum = H_Up;
  2020.                                  break;
  2021.                              case DOWN_GADGET:
  2022.                                  HNum = H_Down;
  2023.                                  break;
  2024.                              case LEFT_GADGET:
  2025.                                  HNum = H_Left;
  2026.                                  break;
  2027.                              case RIGHT_GADGET:
  2028.                                  HNum = H_Right;
  2029.                                  break;
  2030.                              default:
  2031.                                  HNum = H_EWindow;
  2032.                                  break;
  2033.                              }
  2034.                              break;
  2035.                          default:
  2036.                              HNum = H_EWindow;
  2037.                              break;
  2038.                          }
  2039.                      }
  2040.                  }
  2041.                  if (HNum) {
  2042.                      if (GHelp) {
  2043.                          help(HNum);
  2044.                      }
  2045.                      else {
  2046.                          ihelp(HNum);
  2047.                      }
  2048.                  }
  2049.                 break;
  2050.             case IDCMP_NEWSIZE:
  2051.                 // Image resized so resize the gadgets etc.
  2052.                 pic->JustSeconds = 0;    // Note No break !!!!!!!
  2053.             case IDCMP_CHANGEWINDOW:
  2054.                 /* reset window size after change in Zoom
  2055.                  * Changing from 2x to normal size may require the windows
  2056.                  * to be made smaller - this can be delayed by intuition.
  2057.                  * The window limits can only be reset when the window has
  2058.                  * been actually resized.
  2059.                  */
  2060.                 if (ZoomAllowed && !Zoom) {
  2061.                     if (changedboxcount < 3) {
  2062.                         if (WindowLimits(pic->Win,0,0,pic->ilbm->Bmhd.w+pic->Screen->WBorLeft+SIZEIMAGE_W(n),
  2063.                                         pic->ilbm->Bmhd.h+pic->Screen->WBorTop + pic->Screen->Font->ta_YSize+1+SIZEIMAGE_H(n))) {
  2064.                             if (pic == &Pic1) {
  2065.                                 changedboxcount |= 1;
  2066.                             }
  2067.                             else {
  2068.                                 if (pic == &Pic2) {
  2069.                                     changedboxcount |= 2;
  2070.                                 }
  2071.                             }
  2072.                             if (changedboxcount == 3) {
  2073.                                 /* Once both windows have been resized then we
  2074.                                  * can redraw all the points
  2075.                                  */
  2076.                                 DrawAllPoints();
  2077.                             }
  2078.                         }
  2079.                         else {
  2080.                             /* User must have resized in the meantime
  2081.                              * so have another go
  2082.                              */
  2083.                             ChangeWindowBox(pic->Win,pic->Win->LeftEdge,pic->Win->TopEdge,
  2084.                                          min(pic->Win->Width,pic->ilbm->Bmhd.w+pic->Screen->WBorLeft+SIZEIMAGE_W(n)),
  2085.                                          min(pic->Win->Height,pic->ilbm->Bmhd.h+pic->Screen->WBorTop + pic->Screen->Font->ta_YSize+1+SIZEIMAGE_H(n)));
  2086.                         }
  2087.                     }
  2088.                 }
  2089.                 // Reset gadgets etc. for new size
  2090.                 doNewSize(pic);
  2091.                 break;
  2092.              case IDCMP_VANILLAKEY:
  2093.                   switch (msg->Code) {
  2094.                 // Edit Mode ???? - set the relevant mode
  2095.                   case '1':
  2096.                       MySetMode(EDIT1);
  2097.                       break;
  2098.                  case '2':
  2099.                       MySetMode(EDIT2);
  2100.                       break;
  2101.                 case '3':
  2102.                     MySetMode(EDITREL);
  2103.                       break;
  2104.                 case '4':
  2105.                     MySetMode(ADD);
  2106.                       break;
  2107.                 case '5':
  2108.                     MySetMode(DELETE);
  2109.                       break;
  2110.                 case '6':
  2111.                     MySetMode(LINK1);
  2112.                       break;
  2113.                 case '7':
  2114.                     MySetMode(UNLINK1);
  2115.                       break;
  2116.                 case '8':
  2117.                     MySetMode(NONE);
  2118.                     break;
  2119.                 default:
  2120.                     break;
  2121.                 }
  2122.                 break;
  2123.               case IDCMP_RAWKEY:
  2124.                   // Only raw key currently used is the help key
  2125.                   switch (msg->Code) {
  2126.                  case 0x5F:
  2127.                      /* Determine the gadget the pointer is over
  2128.                       * or show help on the whole window
  2129.                       */
  2130.                     X = msg->IDCMPWindow->MouseX;
  2131.                     Y = msg->IDCMPWindow->MouseY;
  2132.                     if (PointInBox(X,Y,0,0,
  2133.                                             CLOSEIMAGE_W(n),msg->IDCMPWindow->BorderTop))
  2134.                         HNum = H_EClose;
  2135.                     else
  2136.                     if (PointInBox(X,Y,(msg->IDCMPWindow->Width - DEPTHIMAGE_W(n)),0,
  2137.                                             msg->IDCMPWindow->Width,msg->IDCMPWindow->BorderTop))
  2138.                         HNum = H_EDepth;
  2139.                     else
  2140.                     if (PointInBox(X,Y,(msg->IDCMPWindow->Width - DEPTHIMAGE_W(n) - ZOOMIMAGE_W(n)),0,
  2141.                                             (msg->IDCMPWindow->Width - DEPTHIMAGE_W(n)),msg->IDCMPWindow->BorderTop))
  2142.                         HNum = H_EZoom;
  2143.                     else
  2144.                     if (PointInBox(X,Y,(msg->IDCMPWindow->Width - SIZEIMAGE_W(n)),(msg->IDCMPWindow->Height-10),
  2145.                                             msg->IDCMPWindow->Width,msg->IDCMPWindow->Height))
  2146.                         HNum = H_ESize;
  2147.                     else
  2148.                     if (PointInBox(X,Y,(msg->IDCMPWindow->Width-SIZEIMAGE_W(n)-LEFTIMAGE_W(n)-RIGHTIMAGE_W(n)),(msg->IDCMPWindow->Height-LEFTIMAGE_H(n)),
  2149.                                             (msg->IDCMPWindow->Width-SIZEIMAGE_W(n)-RIGHTIMAGE_W(n)),msg->IDCMPWindow->Height))
  2150.                         HNum = H_Left;
  2151.                     else
  2152.                     if (PointInBox(X,Y,(msg->IDCMPWindow->Width-SIZEIMAGE_W(n)-RIGHTIMAGE_W(n)),(msg->IDCMPWindow->Height-RIGHTIMAGE_H(n)),
  2153.                                             (msg->IDCMPWindow->Width-SIZEIMAGE_W(n)),msg->IDCMPWindow->Height))
  2154.                         HNum = H_Right;
  2155.                     else
  2156.                     if (PointInBox(X,Y,(msg->IDCMPWindow->Width-UPIMAGE_W(n)),(msg->IDCMPWindow->Height-SIZEIMAGE_H(n)-DOWNIMAGE_H(n)-UPIMAGE_H(n)),
  2157.                                             msg->IDCMPWindow->Width,(msg->IDCMPWindow->Height-SIZEIMAGE_H(n)-DOWNIMAGE_H(n))))
  2158.                         HNum = H_Up;
  2159.                     else
  2160.                     if (PointInBox(X,Y,(msg->IDCMPWindow->Width-UPIMAGE_W(n)),(msg->IDCMPWindow->Height-SIZEIMAGE_H(n)-DOWNIMAGE_H(n)),
  2161.                                             msg->IDCMPWindow->Width,(msg->IDCMPWindow->Height-SIZEIMAGE_H(n))))
  2162.                         HNum = H_Down;
  2163.                     else
  2164.                     if (PointInBox(X,Y,0,(msg->IDCMPWindow->Height-SIZEIMAGE_H(n)),
  2165.                                             (msg->IDCMPWindow->Width-SIZEIMAGE_W(n)-LEFTIMAGE_W(n)-RIGHTIMAGE_W(n)),msg->IDCMPWindow->Height))
  2166.                         HNum = H_Horiz;
  2167.                     else
  2168.                     if (PointInBox(X,Y,(msg->IDCMPWindow->Width-SIZEIMAGE_W(n)),msg->IDCMPWindow->BorderTop,
  2169.                                             msg->IDCMPWindow->Width,(msg->IDCMPWindow->Height-SIZEIMAGE_H(n)-UPIMAGE_H(n)-DOWNIMAGE_H(n))))
  2170.                         HNum = H_Vert;
  2171.                     else
  2172.                         HNum = H_EWindow;
  2173.                     help(HNum);
  2174.                       break;
  2175.                   default:
  2176.                       // some other key
  2177.                       break;
  2178.                   }
  2179.                   break;
  2180.               case IDCMP_MENUHELP:
  2181.                   // Display help on Control and Image window menus
  2182.                   DoMenuHelp(msg->Code);
  2183.                   break;
  2184.             case IDCMP_ACTIVEWINDOW:
  2185.                 /* Window became active
  2186.                  * Store time so that we can ignore the first click
  2187.                  * (for which we may next recieve a message)
  2188.                  * and change the screen palette (if required)
  2189.                  */
  2190.                 pic->JustSeconds = msg->Seconds;
  2191.                 if (flag == 1) {
  2192.                     ColorWindow(pic);
  2193.                 }
  2194.                 break;
  2195.             case IDCMP_INACTIVEWINDOW:
  2196.                 /* Window just became inactive
  2197.                  * change the screen palette back if required
  2198.                  */
  2199.                 UnColorWindow(pic);
  2200.                 break;
  2201.             case IDCMP_MENUVERIFY:
  2202.                 /* Somebody wants to display a menu
  2203.                  * If it is somebody else then just let them
  2204.                  * otherwise if the left mouse button is down then
  2205.                  * do not display the menu as we are going to use
  2206.                  * the right button up/down message to cancel the current action
  2207.                  * otherwise change the screen palette back if required
  2208.                  * so that our menus can be readably displayed
  2209.                  */
  2210.                 switch (msg->Code) {
  2211.                 case MENUWAITING:
  2212.                     break;
  2213.                 case MENUHOT:
  2214.                     pic->JustSeconds = 0;
  2215.                     if (SelDown) {
  2216.                         msg->Code = MENUCANCEL;
  2217.                     }
  2218.                     else {
  2219.                         UnColorWindow(pic);
  2220.                     }
  2221.                     break;
  2222.                 default:
  2223.                     break;
  2224.                 }
  2225.                 break;
  2226.               case IDCMP_MENUPICK:
  2227.                   // Menu item selected, use any further clicks and loop round menu selections
  2228.                 pic->JustSeconds = 0;
  2229.                 Selection = msg->Code;
  2230.                 while ((Selection != MENUNULL) && flag) {
  2231.                     flag = DoMenu(pic,Selection);
  2232.                     Selection = ((struct MenuItem *)ItemAddress(MyMenu,(LONG)Selection))->NextSelect;
  2233.                  }
  2234.                  /* If we are changing palettes and quit
  2235.                   * was not just selected then change
  2236.                   * palette back to the image palette
  2237.                   * after a menu selections
  2238.                   */
  2239.                 if (palette && pic && (flag==1)) {
  2240.                     ColorWindow(pic);
  2241.                 }
  2242.                 break;
  2243.              case IDCMP_CLOSEWINDOW:
  2244.                  /* Close the window with Control and other image windows
  2245.                   * and change the palette back to original if required
  2246.                   */
  2247.                  UnColorWindow(pic);
  2248.                 flag = 2;
  2249.                   break;
  2250.             case IDCMP_MOUSEBUTTONS:
  2251.                 /* Somebody pressed a button
  2252.                  * If the second is the same as the activate window
  2253.                  * message then ignore this click
  2254.                  */
  2255.                 if (pic->JustSeconds && (pic->JustSeconds == msg->Seconds)) {
  2256.                     pic->JustSeconds = 0;
  2257.                 }
  2258.                 else {
  2259.                     /* otherwise process the mouse click/release */
  2260.                     pic->JustSeconds = 0;
  2261.                     switch (msg->Code) {
  2262.                     case SELECTDOWN:
  2263.                         /* Left button pressed
  2264.                          * remember the currentimage positions
  2265.                          * in case Cancelled
  2266.                          */
  2267.                         SelDown = TRUE;
  2268.                         OldLeft = pic->Left;
  2269.                         OldTop = pic->Top;
  2270.                         if (pic == &Pic1) {
  2271.                             OldLeft1 = Pic2.Left;
  2272.                             OldTop1 = Pic2.Top;
  2273.                         }
  2274.                         else {
  2275.                             OldLeft1 = Pic1.Left;
  2276.                             OldTop1 = Pic1.Top;
  2277.                         }
  2278.                         if (Pic1_Open && Pic2_Open) {
  2279.                             // both windows open so action current mode
  2280.                             switch(Mode) {
  2281.                             case EDIT1:
  2282.                                 /* moving points in one window
  2283.                                  * Find point near click
  2284.                                  * erase and draw in new position
  2285.                                  */
  2286.                                 if (MyPoint = FindPoint(pic,(pic->Win->GZZMouseX + Zoom) >> Zoom,(pic->Win->GZZMouseY + Zoom) >> Zoom)) {
  2287.                                     if (pic == &Pic2) {
  2288.                                         DrawPixels(pic,MyPoint->x1,MyPoint->y1,MyPoint);
  2289.                                     }
  2290.                                     else {
  2291.                                         DrawPixels(pic,MyPoint->x,MyPoint->y,MyPoint);
  2292.                                     }
  2293.                                     CurX=(pic->Win->GZZMouseX + Zoom + pic->Left)>>Zoom;
  2294.                                     CurY=(pic->Win->GZZMouseY + Zoom + pic->Top)>>Zoom;
  2295.                                     LimitPoints(&CurX,&CurY,pic);
  2296.                                     DrawPixels(pic,CurX,CurY,MyPoint);
  2297.                                 }
  2298.                                 else {
  2299.                                     SelDown = FALSE;
  2300.                                 }
  2301.                                 break;
  2302.                             case EDIT2:
  2303.                                 /* moving points in both windows
  2304.                                  * Find point near click
  2305.                                  * erase and draw in new positions
  2306.                                  */
  2307.                                 if (MyPoint = FindPoint(pic,(pic->Win->GZZMouseX + Zoom) >> Zoom,(pic->Win->GZZMouseY + Zoom) >> Zoom)) {
  2308.                                     DrawPixels(&Pic1,MyPoint->x,MyPoint->y,MyPoint);
  2309.                                     DrawPixels(&Pic2,MyPoint->x1,MyPoint->y1,MyPoint);
  2310.                                     CurX=(pic->Win->GZZMouseX + Zoom + pic->Left)>>Zoom;
  2311.                                     CurY=(pic->Win->GZZMouseY + Zoom + pic->Top)>>Zoom;
  2312.                                     LimitPoints(&CurX,&CurY,pic);
  2313.                                     DrawPixels(pic,CurX,CurY,MyPoint);
  2314.                                     if (pic == &Pic1) {
  2315.                                         DrawPixels(&Pic2,CurX,CurY,MyPoint);
  2316.                                     }
  2317.                                     else {
  2318.                                         DrawPixels(&Pic1,CurX,CurY,MyPoint);
  2319.                                     }    
  2320.                                 }
  2321.                                 else {
  2322.                                     SelDown = FALSE;
  2323.                                 }
  2324.                                 break;
  2325.                             case EDITREL:
  2326.                                 /* moving points relatively in both windows
  2327.                                  * Find point near click
  2328.                                  * erase and draw in new positions
  2329.                                  */
  2330.                                 if (MyPoint = FindPoint(pic,(pic->Win->GZZMouseX + Zoom) >> Zoom,(pic->Win->GZZMouseY + Zoom) >> Zoom)) {
  2331.                                     DrawPixels(&Pic1,MyPoint->x,MyPoint->y,MyPoint);
  2332.                                     DrawPixels(&Pic2,MyPoint->x1,MyPoint->y1,MyPoint);
  2333.                                     CurX=(pic->Win->GZZMouseX + Zoom + pic->Left)>>Zoom;
  2334.                                     CurY=(pic->Win->GZZMouseY + Zoom + pic->Top)>>Zoom;
  2335.                                     LimitPoints(&CurX,&CurY,pic);
  2336.                                     if (pic == &Pic1) {
  2337.                                         CurX1 = CurX - MyPoint->x + MyPoint->x1;
  2338.                                         CurY1 = CurY - MyPoint->y + MyPoint->y1;
  2339.                                     }
  2340.                                     else {
  2341.                                         CurX1 = CurX - MyPoint->x1 + MyPoint->x;
  2342.                                         CurY1 = CurY - MyPoint->y1 + MyPoint->y;
  2343.                                     }
  2344.                                     LimitPoints(&CurX1,&CurY1,pic);
  2345.                                     DrawPixels(pic,CurX,CurY,MyPoint);
  2346.                                     if (pic == &Pic1) {
  2347.                                         DrawPixels(&Pic2,CurX1,CurY1,MyPoint);
  2348.                                     }
  2349.                                     else {
  2350.                                         DrawPixels(&Pic1,CurX1,CurY1,MyPoint);
  2351.                                     }    
  2352.                                 }
  2353.                                 else {
  2354.                                     SelDown = FALSE;
  2355.                                 }
  2356.                                 break;
  2357.                             case ADD:
  2358.                                 /* Adding point to both windows
  2359.                                  * Draw in both windows
  2360.                                  */
  2361.                                 CurX=(pic->Win->GZZMouseX + Zoom+pic->Left) >> Zoom;
  2362.                                 CurY=(pic->Win->GZZMouseY + Zoom+pic->Top) >> Zoom;
  2363.                                 LimitPoints(&CurX,&CurY,pic);
  2364.                                 DrawPixels(pic,CurX,CurY,NULL);
  2365.                                 if (pic == &Pic1) {
  2366.                                     DrawPixels(&Pic2,CurX,CurY,NULL);
  2367.                                 }
  2368.                                 else {
  2369.                                     DrawPixels(&Pic1,CurX,CurY,NULL);
  2370.                                 }    
  2371.                                 break;
  2372.                             case DELETE:
  2373.                                 /* Deleting point from both windows
  2374.                                  * Erase in both windows - if found
  2375.                                  */
  2376.                                 if (MyPoint = FindPoint(pic,(pic->Win->GZZMouseX + Zoom) >> Zoom,(pic->Win->GZZMouseY + Zoom) >> Zoom)) {
  2377.                                     DrawPixels(&Pic1,MyPoint->x,MyPoint->y,MyPoint);
  2378.                                     DrawPixels(&Pic2,MyPoint->x1,MyPoint->y1,MyPoint);
  2379.                                 }
  2380.                                 else {
  2381.                                     SelDown = FALSE;
  2382.                                 }
  2383.                                 break;
  2384.                             case LINK1:
  2385.                                 /* Linking two points
  2386.                                  * Selecting first point
  2387.                                  * If we can find it then check its not already linked to
  2388.                                  * 4 points then set up the new mode - finding 2nd point
  2389.                                  */
  2390.                                 if (MyPoint = FindPoint(pic,(pic->Win->GZZMouseX + Zoom) >> Zoom,(pic->Win->GZZMouseY + Zoom) >> Zoom)) {
  2391.                                     if (MyPoint->p1 && MyPoint->p2 && MyPoint->p3 && MyPoint->p4) {
  2392.                                           SelDown = FALSE;
  2393.                                         XError(pic,"Point already linked to 4 points","OK",NULL,HE_4points);
  2394.                                     }
  2395.                                     else {
  2396.                                           SetWindowTitles(ControlWindow,"L2",(UBYTE *)-1);
  2397.                                         Mode = LINK2;
  2398.                                         SetMyPointer();
  2399.                                     }
  2400.                                 }
  2401.                                 else {
  2402.                                     SelDown = FALSE;
  2403.                                 }
  2404.                                 break;
  2405.                             case UNLINK1:
  2406.                                 /* Unlinking two points
  2407.                                  * Selecting first point
  2408.                                  * If we can find it then check its already linked
  2409.                                  * then set up the new mode - finding 2nd point
  2410.                                  */
  2411.                                 if (MyPoint = FindPoint(pic,(pic->Win->GZZMouseX + Zoom) >> Zoom,(pic->Win->GZZMouseY + Zoom) >> Zoom)) {
  2412.                                     if (MyPoint->p1 || MyPoint->p2 || MyPoint->p3 || MyPoint->p4) {
  2413.                                           SetWindowTitles(ControlWindow,"U2",(UBYTE *)-1);
  2414.                                         Mode = UNLINK2;
  2415.                                         SetMyPointer();
  2416.                                     }
  2417.                                     else {
  2418.                                         SelDown = FALSE;
  2419.                                         XError(pic,"Point not linked","OK",NULL,HE_NotLinked);
  2420.                                     }
  2421.                                 }
  2422.                                 else {
  2423.                                     SelDown = FALSE;
  2424.                                 }
  2425.                                 break;
  2426.                             case LINK2:
  2427.                                 /* Linking two points
  2428.                                  * Selecting 2nd point
  2429.                                  * If we can find it then do some validation
  2430.                                  * then set up the new mode
  2431.                                  */
  2432.                                 if (MyPoint1 = FindPoint(pic,(pic->Win->GZZMouseX + Zoom) >> Zoom,(pic->Win->GZZMouseY + Zoom) >> Zoom)) {
  2433.                                     if (MyPoint == MyPoint1) {
  2434.                                           SelDown = FALSE;
  2435.                                         XError(pic,"Cannot link point to itself","OK",NULL,HE_LinkSelf);
  2436.                                     }
  2437.                                     else {
  2438.                                         if (MyPoint1->p1 && MyPoint1->p2 && MyPoint1->p3 && MyPoint1->p4) {
  2439.                                               SelDown = FALSE;
  2440.                                             XError(pic,"Point already linked to 4 points","OK",NULL,HE_4points);
  2441.                                         }
  2442.                                         else {
  2443.                                             if ((MyPoint->p1 == MyPoint1) || (MyPoint->p2 == MyPoint1) ||
  2444.                                                  (MyPoint->p3 == MyPoint1) || (MyPoint->p4 == MyPoint1)) {
  2445.                                                   SelDown = FALSE;
  2446.                                                 XError(pic,"Points already linked","OK",NULL,HE_Linked);
  2447.                                             }
  2448.                                             else {
  2449.                                                 LinkPoints(MyPoint,MyPoint1);
  2450.                                                 Mode = LINK2A;
  2451.                                             }
  2452.                                         }
  2453.                                     }
  2454.                                 }
  2455.                                 break;
  2456.                             case UNLINK2:
  2457.                                 /* Unlinking two points
  2458.                                  * Selecting 2nd point
  2459.                                  * If we can find it then do some validation
  2460.                                  * then set up the new mode
  2461.                                  */
  2462.                                 if (MyPoint1 = FindPoint(pic,(pic->Win->GZZMouseX + Zoom) >> Zoom,(pic->Win->GZZMouseY + Zoom) >> Zoom)) {
  2463.                                     if (MyPoint == MyPoint1) {
  2464.                                         SelDown = FALSE;
  2465.                                         XError(pic,"Cannot unlink point from itself","OK",NULL,HE_UnlinkSelf);
  2466.                                     }
  2467.                                     else {
  2468.                                         if ((MyPoint->p1 != MyPoint1) && (MyPoint->p2 != MyPoint1) &&
  2469.                                              (MyPoint->p3 != MyPoint1) && (MyPoint->p4 != MyPoint1)) {
  2470.                                             SelDown = FALSE;
  2471.                                             XError(pic,"Point not linked","OK",NULL,HE_NotLinked);
  2472.                                         }
  2473.                                         else {
  2474.                                             UnlinkPoints(MyPoint,MyPoint1,TRUE);
  2475.                                             Mode = UNLINK2A;
  2476.                                         }
  2477.                                     }
  2478.                                 }
  2479.                                 break;
  2480.                             default:
  2481.                                 // Some other mode?
  2482.                                 break;
  2483.                             }
  2484.                             /* If we are adding a point, or moving a point
  2485.                              * then we may need to scroll the other window
  2486.                              * to get the point in view
  2487.                              * So update the gadgets and check the values set up
  2488.                              */
  2489.                             if ((Mode == ADD) || 
  2490.                                  ((MyPoint) && ((Mode == EDIT2) || (Mode == EDITREL)))) {
  2491.                                 if (pic == &Pic1) {
  2492.                                     pic1 = &Pic2;
  2493.                                 }
  2494.                                 else {
  2495.                                     pic1 = &Pic1;
  2496.                                 }
  2497.                                 if (Mode != EDITREL) {
  2498.                                     // if not edit rel then both points are in the same position
  2499.                                     CurX1 = CurX;
  2500.                                     CurY1 = CurY;
  2501.                                 }
  2502.                                 pic1->XLeft=pic1->Left;
  2503.                                 pic1->XTop=pic1->Top;
  2504.                                 if ((CurY1<<Zoom) < pic1->Top) {
  2505.                                     pic1->Top = CurY1<<Zoom;
  2506.                                     SetGadgetAttrs(pic1->SideGad, pic1->Win, NULL,
  2507.                                         PGA_Top, pic1->Top, TAG_END);
  2508.                                 }
  2509.                                 if ((CurX1<<Zoom) < pic1->Left) {
  2510.                                     pic1->Left = CurX1<<Zoom;
  2511.                                     SetGadgetAttrs(pic1->BotGad, pic1->Win, NULL,
  2512.                                     PGA_Top, pic1->Left, TAG_END);
  2513.                                 }
  2514.                                 if ((CurY1<<Zoom) > (pic1->Win->GZZHeight+pic1->Top)) {
  2515.                                     pic1->Top = ((CurY1<<Zoom) - pic1->Win->GZZHeight);
  2516.                                     SetGadgetAttrs(pic1->SideGad, pic1->Win, NULL,
  2517.                                         PGA_Top, pic1->Top, TAG_END);
  2518.                                 }
  2519.                                 if ((CurX1<<Zoom) > (pic1->Win->GZZWidth+pic1->Left)) {
  2520.                                     pic1->Left = ((CurX1<<Zoom) - pic1->Win->GZZWidth);
  2521.                                     SetGadgetAttrs(pic1->BotGad, pic1->Win, NULL,
  2522.                                         PGA_Top, pic1->Left, TAG_END);
  2523.                                 }
  2524.                                 checkGadget(pic1);
  2525.                             }
  2526.                         }
  2527.                         break;
  2528.                     case SELECTUP:
  2529.                         /* Left mouse button up
  2530.                          * If we are currently doing something then
  2531.                          * this actually confirms we really want
  2532.                          * to do it, Saved is set to FALSE following any change
  2533.                          */
  2534.                         if (SelDown) {
  2535.                             SelDown = FALSE;
  2536.                             switch(Mode) {
  2537.                             case ADD:
  2538.                                 // Adding a point, Create and add to list
  2539.                                 if (MyPoint = AllocMem(sizeof(struct MyPoint),MEMF_CLEAR)) {
  2540.                                     MyPoint->x = CurX;
  2541.                                     MyPoint->y = CurY;
  2542.                                     MyPoint->x1 = CurX;
  2543.                                     MyPoint->y1 = CurY;
  2544.                                     MaxWidth = max(CurX,MaxWidth);
  2545.                                     MaxHeight = max(CurY,MaxHeight);
  2546.                                     AddTail(&PointList,(struct Node *)MyPoint);
  2547.                                     Saved = FALSE;
  2548.                                 }
  2549.                                 else {
  2550.                                     XError(pic,"Error no memory for new point","OK",NULL,HE_MemNewPoint);
  2551.                                 }
  2552.                                 break;
  2553.                             case EDIT1:
  2554.                                 // Editing one window, update actual point
  2555.                                 if (pic == &Pic2) {
  2556.                                     MyPoint->x1 = CurX;
  2557.                                     MyPoint->y1 = CurY;
  2558.                                 }
  2559.                                 else {
  2560.                                     MyPoint->x = CurX;
  2561.                                     MyPoint->y = CurY;
  2562.                                 }
  2563.                                 Saved = FALSE;
  2564.                                 break;
  2565.                             case EDIT2:
  2566.                                 // Editing two windows, update actual point
  2567.                                 MyPoint->x = CurX;
  2568.                                 MyPoint->y = CurY;
  2569.                                 MyPoint->x1 = CurX;
  2570.                                 MyPoint->y1 = CurY;
  2571.                                 Saved = FALSE;
  2572.                                 break;
  2573.                             case EDITREL:
  2574.                                 // Editing relative, update actual point
  2575.                                 if (pic == &Pic1) {
  2576.                                     CurX1 = CurX - MyPoint->x + MyPoint->x1;
  2577.                                     CurY1 = CurY - MyPoint->y + MyPoint->y1;
  2578.                                     MyPoint->x = CurX;
  2579.                                     MyPoint->y = CurY;
  2580.                                 }
  2581.                                 else {
  2582.                                     CurX1 = CurX - MyPoint->x1 + MyPoint->x;
  2583.                                     CurY1 = CurY - MyPoint->y1 + MyPoint->y;
  2584.                                     MyPoint->x1 = CurX;
  2585.                                     MyPoint->y1 = CurY;
  2586.                                 }
  2587.                                 Saved = FALSE;
  2588.                                 LimitPoints(&CurX1,&CurY1,((pic == &Pic1)?&Pic2:&Pic1));
  2589.                                 if (pic == &Pic1) {
  2590.                                     MyPoint->x1 = CurX1;
  2591.                                     MyPoint->y1 = CurY1;
  2592.                                 }
  2593.                                 else {
  2594.                                     MyPoint->x = CurX1;
  2595.                                     MyPoint->y = CurY1;
  2596.                                 }
  2597.                                 break;
  2598.                             case DELETE:
  2599.                                 // Deleting, delete actual point
  2600.                                 if (MyPoint) {
  2601.                                     DeletePoint(MyPoint);
  2602.                                 }
  2603.                                 Saved = FALSE;
  2604.                                 break;
  2605.                             case LINK2A:
  2606.                                 // Linking, reset window title and pointer
  2607.                                   SetWindowTitles(ControlWindow,"L1",(UBYTE *)-1);
  2608.                                 Mode = LINK1;
  2609.                                 Saved = FALSE;
  2610.                                 SetMyPointer();
  2611.                                 break;
  2612.                             case UNLINK2A:
  2613.                                 // Unlinking, reset window title and pointer
  2614.                                   SetWindowTitles(ControlWindow,"U1",(UBYTE *)-1);
  2615.                                 Mode = UNLINK1;
  2616.                                 Saved = FALSE;
  2617.                                 SetMyPointer();
  2618.                                 break;
  2619.                             default:
  2620.                                 break;
  2621.                             }
  2622.                         }
  2623.                         break;
  2624.                     case MENUDOWN:
  2625.                     case MENUUP:
  2626.                         /* Menu button pressed
  2627.                          * Cancel any current action
  2628.                          */
  2629.                         if (SelDown) {
  2630.                             SelDown = FALSE;
  2631.                             switch (Mode) {
  2632.                             case ADD:
  2633.                                 /* Adding,
  2634.                                  * erase points
  2635.                                  */
  2636.                                 DrawPixels(&Pic1,CurX,CurY,NULL);
  2637.                                 DrawPixels(&Pic2,CurX,CurY,NULL);
  2638.                                 break;
  2639.                             case EDIT1:
  2640.                                 /* Editing in one window,
  2641.                                  * erase current postion and redraw in original
  2642.                                  */
  2643.                                 DrawPixels(pic,CurX,CurY,MyPoint);
  2644.                                 if (pic == &Pic2) {
  2645.                                     DrawPixels(pic,MyPoint->x1,MyPoint->y1,MyPoint);
  2646.                                 }
  2647.                                 else {
  2648.                                     DrawPixels(pic,MyPoint->x,MyPoint->y,MyPoint);
  2649.                                 }
  2650.                                 break;
  2651.                             case EDIT2:
  2652.                                 /* Editing in both windows,
  2653.                                  * erase current postion and redraw in original
  2654.                                  */
  2655.                                 DrawPixels(&Pic1,CurX,CurY,MyPoint);
  2656.                                 DrawPixels(&Pic1,MyPoint->x,MyPoint->y,MyPoint);
  2657.                                 DrawPixels(&Pic2,CurX,CurY,MyPoint);
  2658.                                 DrawPixels(&Pic2,MyPoint->x1,MyPoint->y1,MyPoint);
  2659.                                 break;
  2660.                             case EDITREL:
  2661.                                 /* Editing relatively in both windows,
  2662.                                  * erase current postions and redraw in original
  2663.                                  */
  2664.                                 if (pic == &Pic1) {
  2665.                                     DrawPixels(&Pic1,CurX,CurY,MyPoint);
  2666.                                     DrawPixels(&Pic1,MyPoint->x,MyPoint->y,MyPoint);
  2667.                                     DrawPixels(&Pic2,CurX1,CurY1,MyPoint);
  2668.                                     DrawPixels(&Pic2,MyPoint->x1,MyPoint->y1,MyPoint);
  2669.                                 }
  2670.                                 else {
  2671.                                     DrawPixels(&Pic2,CurX,CurY,MyPoint);
  2672.                                     DrawPixels(&Pic2,MyPoint->x1,MyPoint->y1,MyPoint);
  2673.                                     DrawPixels(&Pic1,CurX1,CurY1,MyPoint);
  2674.                                     DrawPixels(&Pic1,MyPoint->x,MyPoint->y,MyPoint);
  2675.                                 }
  2676.                                 break;
  2677.                             case DELETE:
  2678.                                 /* Deleting points
  2679.                                  * Redraw in original position
  2680.                                  */
  2681.                                 DrawPixels(&Pic1,MyPoint->x,MyPoint->y,MyPoint);
  2682.                                 DrawPixels(&Pic2,MyPoint->x1,MyPoint->y1,MyPoint);
  2683.                                 break;
  2684.                             case LINK2A:
  2685.                                 /* Linking points
  2686.                                  * Re-Unlink
  2687.                                  */
  2688.                                 UnlinkPoints(MyPoint,MyPoint1,TRUE);    // no break
  2689.                             case LINK2:
  2690.                                 /* and reset title and pointer */
  2691.                                   SetWindowTitles(ControlWindow,"L1",(UBYTE *)-1);
  2692.                                 Mode = LINK1;
  2693.                                 SetMyPointer();
  2694.                                 break;
  2695.                             case UNLINK2A:
  2696.                                 /* Unlinking points
  2697.                                  * re-link
  2698.                                  */
  2699.                                 LinkPoints(MyPoint,MyPoint1);                // no break
  2700.                             case UNLINK2:
  2701.                                 /* and reset title and pointer */
  2702.                                   SetWindowTitles(ControlWindow,"U1",(UBYTE *)-1);
  2703.                                 Mode = UNLINK1;
  2704.                                 SetMyPointer();
  2705.                                 break;
  2706.                             default:
  2707.                                 // some other mode?
  2708.                                 break;
  2709.                             }
  2710.                             /* Scroll the images back to
  2711.                              * their original position
  2712.                              */
  2713.                             pic->XLeft=pic->Left;
  2714.                             pic->XTop=pic->Top;
  2715.                             pic->Left=OldLeft;
  2716.                             pic->Top=OldTop;
  2717.                             SetGadgetAttrs(pic->SideGad, pic->Win, NULL,
  2718.                                 PGA_Top, pic->Top, TAG_END);
  2719.                             SetGadgetAttrs(pic->BotGad, pic->Win, NULL,
  2720.                                 PGA_Top, pic->Left, TAG_END);
  2721.                             checkGadget(pic); 
  2722.                             if (pic == &Pic1) {
  2723.                                 pic1 = &Pic2;
  2724.                             }
  2725.                             else {
  2726.                                 pic1 = &Pic1;
  2727.                             }
  2728.                             pic1->XLeft=pic1->Left;
  2729.                             pic1->XTop=pic1->Top;
  2730.                             pic1->Left=OldLeft1;
  2731.                             pic1->Top=OldTop1;
  2732.                             SetGadgetAttrs(pic1->SideGad, pic1->Win, NULL,
  2733.                                 PGA_Top, pic1->Top, TAG_END);
  2734.                             SetGadgetAttrs(pic1->BotGad, pic1->Win, NULL,
  2735.                                 PGA_Top, pic1->Left, TAG_END);
  2736.                             checkGadget(pic1); 
  2737.                         }
  2738.                         break;
  2739.                     default:
  2740.                         // Some other mouse button?
  2741.                         break;
  2742.                     }
  2743.                 }
  2744.                 break;
  2745.             case IDCMP_MOUSEMOVE:
  2746.                 /* The mouse moved
  2747.                  * If we are currently doing something
  2748.                  * then update
  2749.                  */
  2750.                 if (SelDown) {
  2751.                     OldX = CurX;
  2752.                     OldY = CurY;
  2753.                     CurX=(pic->Win->GZZMouseX + Zoom+pic->Left) >> Zoom;
  2754.                     CurY=(pic->Win->GZZMouseY + Zoom+pic->Top) >> Zoom;
  2755.                     LimitPoints(&CurX,&CurY,pic);
  2756.                     switch(Mode) {
  2757.                     case EDIT1:
  2758.                         /* Editing one window
  2759.                          * Erase old position
  2760.                          */
  2761.                         DrawPixels(pic,OldX,OldY,MyPoint);
  2762.                         break;
  2763.                     case ADD:
  2764.                         /* Adding
  2765.                          * Erase old positions
  2766.                          */
  2767.                         DrawPixels(&Pic1,OldX,OldY,NULL);
  2768.                         DrawPixels(&Pic2,OldX,OldY,NULL);
  2769.                         break;
  2770.                     case EDIT2:
  2771.                         /* Editing both windows
  2772.                          * Erase old positions
  2773.                          */
  2774.                         DrawPixels(&Pic1,OldX,OldY,MyPoint);
  2775.                         DrawPixels(&Pic2,OldX,OldY,MyPoint);
  2776.                         break;
  2777.                     case EDITREL:
  2778.                         /* Editing relatively both windows
  2779.                          * Erase old positions
  2780.                          */
  2781.                         OldX1 = CurX1;
  2782.                         OldY1 = CurY1;
  2783.                         CurX1 += (CurX - OldX);
  2784.                         CurY1 += (CurY - OldY);
  2785.                         if (pic == &Pic1){
  2786.                             DrawPixels(&Pic1,OldX,OldY,MyPoint);
  2787.                             DrawPixels(&Pic2,OldX1,OldY1,MyPoint);
  2788.                         }
  2789.                         else {
  2790.                             DrawPixels(&Pic1,OldX1,OldY1,MyPoint);
  2791.                             DrawPixels(&Pic2,OldX,OldY,MyPoint);
  2792.                         }
  2793.                         break;
  2794.                     default:
  2795.                         break;
  2796.                     }
  2797.                     // Scroll the current window if required
  2798.                     pic->XLeft=pic->Left;
  2799.                     pic->XTop=pic->Top;
  2800.                     if ((CurY<<Zoom) < pic->Top) {
  2801.                         pic->Top = (CurY<<Zoom);
  2802.                         SetGadgetAttrs(pic->SideGad, pic->Win, NULL,
  2803.                             PGA_Top, pic->Top, TAG_END);
  2804.                     }
  2805.                     if ((CurX<<Zoom) < pic->Left) {
  2806.                         pic->Left = (CurX<<Zoom);
  2807.                         SetGadgetAttrs(pic->BotGad, pic->Win, NULL,
  2808.                             PGA_Top, pic->Left, TAG_END);
  2809.                     }
  2810.                     if ((CurY<<Zoom) > (pic->Win->GZZHeight+pic->Top)) {
  2811.                         pic->Top = ((CurY<<Zoom) - pic->Win->GZZHeight);
  2812.                         SetGadgetAttrs(pic->SideGad, pic->Win, NULL,
  2813.                             PGA_Top, pic->Top, TAG_END);
  2814.                     }
  2815.                     if ((CurX<<Zoom) > (pic->Win->GZZWidth+pic->Left)) {
  2816.                         pic->Left = ((CurX<<Zoom) - pic->Win->GZZWidth);
  2817.                         SetGadgetAttrs(pic->BotGad, pic->Win, NULL,
  2818.                             PGA_Top, pic->Left, TAG_END);
  2819.                     }
  2820.                     checkGadget(pic);
  2821.                     // Draw new positions
  2822.                     switch(Mode) {
  2823.                     case EDIT1:
  2824.                         /* Editing one window
  2825.                          * Draw new position
  2826.                          */
  2827.                         DrawPixels(pic,CurX,CurY,MyPoint);
  2828.                         break;
  2829.                     case ADD:
  2830.                         /* Adding
  2831.                          * Draw new positions
  2832.                          */
  2833.                         DrawPixels(&Pic1,CurX,CurY,NULL);
  2834.                         DrawPixels(&Pic2,CurX,CurY,NULL);
  2835.                         break;
  2836.                     case EDIT2:
  2837.                         /* Editing both windows
  2838.                          * Draw new positions
  2839.                          */
  2840.                         DrawPixels(&Pic1,CurX,CurY,MyPoint);
  2841.                         DrawPixels(&Pic2,CurX,CurY,MyPoint);
  2842.                         break;
  2843.                     case EDITREL:
  2844.                         /* Editing both windows relatively
  2845.                          * Draw new positions
  2846.                          */
  2847.                         LimitPoints(&CurX1,&CurY1,pic);
  2848.                         if (pic == &Pic1){
  2849.                             DrawPixels(&Pic1,CurX,CurY,MyPoint);
  2850.                             DrawPixels(&Pic2,CurX1,CurY1,MyPoint);
  2851.                         }
  2852.                         else {
  2853.                             DrawPixels(&Pic2,CurX,CurY,MyPoint);
  2854.                             DrawPixels(&Pic1,CurX1,CurY1,MyPoint);
  2855.                         }
  2856.                         break;
  2857.                     default:
  2858.                         // Some other mode
  2859.                         break;
  2860.                     }
  2861.                     /* If we are affecting the other window then
  2862.                      * we may need to scroll it
  2863.                      */
  2864.                     if ((Mode == ADD) || (Mode == EDIT2) || (Mode == EDITREL)) {
  2865.                         if (pic == &Pic1) {
  2866.                             pic1 = &Pic2;
  2867.                         }
  2868.                         else {
  2869.                             pic1 = &Pic1;
  2870.                         }
  2871.                         if (Mode != EDITREL) {
  2872.                             // Points both in the same position
  2873.                             CurX1 = CurX;
  2874.                             CurY1 = CurY;
  2875.                         }
  2876.                         pic1->XLeft=pic1->Left;
  2877.                         pic1->XTop=pic1->Top;
  2878.                         if ((CurY1<<Zoom) < pic1->Top) {
  2879.                             pic1->Top = (CurY1<<Zoom);
  2880.                             SetGadgetAttrs(pic1->SideGad, pic1->Win, NULL,
  2881.                                 PGA_Top, pic1->Top, TAG_END);
  2882.                         }
  2883.                         if ((CurX1<<Zoom) < pic1->Left) {
  2884.                             pic1->Left = (CurX1<<Zoom);
  2885.                             SetGadgetAttrs(pic1->BotGad, pic1->Win, NULL,
  2886.                                 PGA_Top, pic1->Left, TAG_END);
  2887.                         }
  2888.                         if ((CurY1<<Zoom) > (pic1->Win->GZZHeight+pic1->Top)) {
  2889.                             pic1->Top = ((CurY1<<Zoom) - pic1->Win->GZZHeight);
  2890.                             SetGadgetAttrs(pic1->SideGad, pic1->Win, NULL,
  2891.                                 PGA_Top, pic1->Top, TAG_END);
  2892.                         }
  2893.                         if ((CurX1<<Zoom) > (pic1->Win->GZZWidth+pic1->Left)) {
  2894.                             pic1->Left = ((CurX1<<Zoom) - pic1->Win->GZZWidth);
  2895.                             SetGadgetAttrs(pic1->BotGad, pic1->Win, NULL,
  2896.                                 PGA_Top, pic1->Left, TAG_END);
  2897.                         }
  2898.                         // Update image scroll
  2899.                         checkGadget(pic1);
  2900.                     }
  2901.                 }
  2902.                 break;
  2903.             case IDCMP_GADGETDOWN:
  2904.                 // Gadget down, save the current gadget id
  2905.                 pic->JustSeconds = 0;
  2906.                 pic->currentg = ((struct Gadget *)(msg->IAddress))->GadgetID;
  2907.                 break;
  2908.             case IDCMP_GADGETUP:
  2909.                 // Gadget up, no current gadget id
  2910.                 pic->JustSeconds = 0;
  2911.                 pic->currentg = NO_GADGET;
  2912.                 break;
  2913.             case IDCMP_IDCMPUPDATE:
  2914.                 // Gadget update message
  2915.                 pic->JustSeconds = 0;
  2916.                 /* If an arrow then check the mouse button
  2917.                  * is down (prevents image scrolling long
  2918.                  * after button is released)
  2919.                  */
  2920.                 if ((pic->currentg == LEFT_RIGHT_GADGET) ||
  2921.                      (pic->currentg == UP_DOWN_GADGET) ||
  2922.                      (PeekQualifier() & IEQUALIFIER_LEFTBUTTON)) {
  2923.                     pic->XLeft=pic->Left;
  2924.                     pic->XTop=pic->Top;
  2925.                     Shift = PeekQualifier() & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT);
  2926.                     switch(pic->currentg) {
  2927.                     case LEFT_RIGHT_GADGET:
  2928.                         // Horizontal gadget - get position
  2929.                         pic->Left = msg->Code;
  2930.                         break;
  2931.                     case UP_DOWN_GADGET:
  2932.                         // Vertical gadget - get position
  2933.                         pic->Top = msg->Code;
  2934.                         break;
  2935.                     case UP_GADGET:
  2936.                         // Up gadget, check shift key
  2937.                         if (pic->Top) {
  2938.                             if (Shift)
  2939.                                 --(pic->Top);
  2940.                             else
  2941.                             if (pic->Top > pic->ATop)
  2942.                                     pic->Top -= pic->ATop;
  2943.                                 else
  2944.                                     pic->Top = 0;
  2945.                             SetGadgetAttrs(pic->SideGad, pic->Win, NULL,
  2946.                                 PGA_Top, pic->Top, TAG_END);
  2947.                         }
  2948.                         break;
  2949.                     case LEFT_GADGET:
  2950.                         // Left gadget, check shift key
  2951.                         if (pic->Left) {
  2952.                             if (Shift)
  2953.                                 --(pic->Left);
  2954.                             else
  2955.                                 if (pic->Left > pic->ALeft)
  2956.                                     pic->Left -= pic->ALeft;
  2957.                                 else
  2958.                                     pic->Left = 0;
  2959.                             SetGadgetAttrs(pic->BotGad, pic->Win, NULL,
  2960.                                 PGA_Top, pic->Left, TAG_END);
  2961.                         }
  2962.                         break;
  2963.                     case DOWN_GADGET:
  2964.                         // Down gadget, check shift key
  2965.                         if (Shift)
  2966.                             ++(pic->Top);
  2967.                         else
  2968.                             pic->Top += pic->ATop;
  2969.                         if (pic->Top > pic->MTop)
  2970.                             pic->Top = pic->MTop;
  2971.                         SetGadgetAttrs(pic->SideGad, pic->Win, NULL,
  2972.                             PGA_Top, pic->Top, TAG_END);
  2973.                         break;
  2974.                     case RIGHT_GADGET:
  2975.                         // Right gadget, check shift key
  2976.                         if (Shift)
  2977.                             ++(pic->Left);
  2978.                         else
  2979.                             pic->Left += pic->ALeft;
  2980.                         if (pic->Left > pic->MLeft)
  2981.                             pic->Left = pic->MLeft;
  2982.                         SetGadgetAttrs(pic->BotGad, pic->Win, NULL,
  2983.                             PGA_Top, pic->Left, TAG_END);
  2984.                         break;
  2985.                     }
  2986.                     // Update image scroll
  2987.                     checkGadget(pic); 
  2988.                     break;
  2989.                 }
  2990.             }
  2991.             ReplyMsg((struct Message *)msg);
  2992.          }
  2993.         }
  2994.         /* If a window was closed etc.
  2995.          * then turn on some menus and close the windows
  2996.          * etc.
  2997.          */
  2998.         if ((flag == 2) || (flag == 3)) {
  2999.             if ((flag == 2) &&
  3000.                  ((SinglePicture == 2) || (SinglePicture == 3))) {
  3001.                 if (!Saved) {
  3002.                     flag = SaveRequester();
  3003.                 }
  3004.                 DeleteAllPoints();
  3005.             }
  3006.             if (flag) {
  3007.                 OnMenu(TSMorphWnd,FULLMENUNUM(0,0,NOSUB));
  3008.                 OnMenu(TSMorphWnd,FULLMENUNUM(0,1,NOSUB));
  3009.                 if (Pic1_Open) {
  3010.                     CloseAPicture(&Pic1);
  3011.                     Pic1_Open = FALSE;
  3012.                 }
  3013.                 if (Pic2_Open) {
  3014.                     CloseAPicture(&Pic2);
  3015.                     Pic2_Open = FALSE;
  3016.                 }
  3017.                 CloseControlWindow();
  3018.             }
  3019.             // Below just updates the correct gadgets
  3020.             EnableWindows();
  3021.              flag = 1;
  3022.         }
  3023.     }
  3024. }
  3025.  
  3026. /* SetPointer
  3027.  * based on the current mode
  3028.  */
  3029. void
  3030. SetMyPointer(void) {
  3031.     UWORD __chip *Pointer;    // Pointer image
  3032.     // Set pointer based on mode
  3033.     switch (Mode) {
  3034.     case EDIT1:
  3035.         Pointer = One;
  3036.          break;
  3037.     case EDIT2:
  3038.         Pointer = Two;
  3039.         break;
  3040.     case EDITREL:
  3041.         Pointer = Rel;
  3042.         break;
  3043.     case ADD:
  3044.         Pointer = Add;
  3045.         break;
  3046.     case DELETE:
  3047.         Pointer = Del;
  3048.         break;
  3049.     case LINK1:
  3050.         Pointer = L1;
  3051.         break;
  3052.     case UNLINK1:
  3053.         Pointer = U1;
  3054.         break;
  3055.     case NONE:
  3056.         Pointer = Mov;
  3057.         break;
  3058.     case UNLINK2:
  3059.         Pointer = U2;
  3060.         break;
  3061.     case LINK2:
  3062.         Pointer = L2;
  3063.         break;
  3064.     }
  3065.     // Set the window pointers
  3066.     if (Pic1_Open) {
  3067.         SetPointer(Pic1.Win, Pointer, 16, 16, -1, 0);
  3068.     }
  3069.     if (Pic2_Open) {
  3070.         SetPointer(Pic2.Win, Pointer, 16, 16, -1, 0);
  3071.     }
  3072.     if (ControlWindow) {
  3073.         SetPointer(ControlWindow, Pointer, 16, 16, -1, 0);
  3074.     }
  3075. }
  3076.  
  3077. /* Do the Control and image window menus
  3078.  * Returns    : 1 = OK, 0 = quit, 2=exit points
  3079.  * pic        : Picture structure if an image window
  3080.  * Selection: Menu item
  3081.  */
  3082. int
  3083. DoMenu(struct Picture *pic,UWORD Selection) {
  3084.     int flag = 1;            // Return value
  3085.     // Large switch statements for menu items
  3086.       switch (MENUNUM(Selection)) {
  3087.       case M_PROJECT:
  3088.         switch(ITEMNUM(Selection)) {
  3089.         case MM_NEW:
  3090.             /* New Points
  3091.              * Suggest Save if not saved
  3092.              * then delete all point
  3093.              */
  3094.             DisableWindows(DI_New);
  3095.             if (!Saved) {
  3096.                 if (SaveRequester()) {
  3097.                     Saved = TRUE;
  3098.                 }
  3099.             }
  3100.             if (Saved) {
  3101.                 DeleteAllPoints();
  3102.                 MaxWidth = 0;
  3103.                 MaxHeight = 0;
  3104.                 Saved = FALSE;
  3105.             }
  3106.             EnableWindows();
  3107.             break;
  3108.         case MM_OPEN:
  3109.             // Open Points - just call MyOpen() with JustPoints=TRUE
  3110.             DisableWindows(DI_WaitOpen);
  3111.             MyOpen(NULL,TRUE,TRUE);
  3112.             EnableWindows();
  3113.             break;
  3114.         case MM_SAVE:
  3115.             // Save - just call SaveAs() with last filename
  3116.             DisableWindows(DI_WaitSave);
  3117.             SaveAs(savedfilename);
  3118.             EnableWindows();
  3119.             break;
  3120.         case MM_SAVEAS:
  3121.             // Save - just call SaveAs() with no filename
  3122.             DisableWindows(DI_WaitSave);
  3123.             SaveAs(NULL);
  3124.             EnableWindows();
  3125.             break;
  3126.           case MM_ABOUT:
  3127.               // About - display requester
  3128.             DisableWindows(DI_About);
  3129.             About();
  3130.             EnableWindows();
  3131.             break;
  3132.         case MM_EXITPOINTS:
  3133.             // Exit Points - Close Image and control windows
  3134.             flag = 2;
  3135.             break;
  3136.         case MM_QUIT:
  3137.             // Quit - Suggest save first
  3138.             if (!Saved) {
  3139.                   flag = !SaveRequester();
  3140.               }
  3141.               else {
  3142.                   flag = 0;
  3143.               }
  3144.             break;
  3145.         case MM_PPREVIEW:
  3146.             Preview();
  3147.             break;
  3148.          default:
  3149.              // Some other item
  3150.               break;
  3151.         }
  3152.         break;
  3153.     case M_EDIT:
  3154.         switch(ITEMNUM(Selection)) {
  3155.         case MM_GRID:
  3156.             // Add Grid... - Add a grid of points
  3157.             AddGrid();
  3158.             break;
  3159.         case MM_FRAME:
  3160.             // Frame sub menu
  3161.             switch (SUBNUM(Selection)) {
  3162.             case MI_FIRST:
  3163.                 flag = FirstFrame();
  3164.                 break;
  3165.             case MI_PREV:
  3166.                 flag = PrevFrame();
  3167.                 break;
  3168.             case MI_GOTO:
  3169.                 flag = GotoFrame();
  3170.                 break;
  3171.             case MI_NEXT:
  3172.                 flag = NextFrame();
  3173.                 break;
  3174.             case MI_LAST:
  3175.                 flag = LastFrame();
  3176.                 break;
  3177.             default:
  3178.                 break;
  3179.             }
  3180.             break;
  3181.         case MM_MODE:
  3182.             switch (SUBNUM(Selection)) {
  3183.             // Edit Mode ???? - set the relevant mode
  3184.               case MI_EDITONE:
  3185.                   MySetMode(EDIT1);
  3186.                   break;
  3187.              case MI_EDITTWO:
  3188.                   MySetMode(EDIT2);
  3189.                   break;
  3190.             case MI_EDITREL:
  3191.                 MySetMode(EDITREL);
  3192.                   break;
  3193.             case MI_ADD:
  3194.                 MySetMode(ADD);
  3195.                   break;
  3196.             case MI_DELETE:
  3197.                 MySetMode(DELETE);
  3198.                   break;
  3199.             case MI_LINK:
  3200.                 MySetMode(LINK1);
  3201.                   break;
  3202.             case MI_UNLINK:
  3203.                 MySetMode(UNLINK1);
  3204.                   break;
  3205.             case MI_NONE:
  3206.                 MySetMode(NONE);
  3207.                 break;
  3208.             default:
  3209.                 break;
  3210.             }
  3211.             break;
  3212.         default:
  3213.             // Some other item
  3214.             break;
  3215.         }
  3216.         break;
  3217.     case M_SETTINGS:
  3218.         HandleSettings(Selection,pic);
  3219.         break;
  3220.     default:
  3221.         // something else ??
  3222.         break;
  3223.     }
  3224.     // return 0,1 or 2
  3225.     return flag;
  3226. }
  3227.  
  3228. /* Disable all windows,
  3229.  * menus, pointers,
  3230.  * gadgets etc.
  3231.  *
  3232.  * Note: This must be able to be called multiple times without EnableWindows()
  3233.  */
  3234. void
  3235. DisableWindows(ULONG dnum) {
  3236.     if (dnum < 1000) {
  3237.         ihelp(dnum);
  3238.     }
  3239.     else {
  3240.         if (*(disabled[dnum-1000])) {
  3241.             if (TSMorphWnd) {
  3242.                 GT_SetGadgetAttrs(TSMorphGadgets[GDX_Help],TSMorphWnd,NULL,
  3243.                                     GTTX_Text,disabled[dnum-1000], TAG_END );
  3244.             }
  3245.         }
  3246.     }
  3247.     if (ControlWindow) {
  3248.         // All 3 menus off
  3249.         OffMenu(ControlWindow,FULLMENUNUM(M_PROJECT,NOITEM,NOSUB));
  3250.         OffMenu(ControlWindow,FULLMENUNUM(M_EDIT,NOITEM,NOSUB));
  3251.         OffMenu(ControlWindow,FULLMENUNUM(M_SETTINGS,NOITEM,NOSUB));
  3252.         // All gadgets off
  3253.         OffGadget(&OneGadget,ControlWindow,NULL);
  3254.         OffGadget(&TwoGadget,ControlWindow,NULL);
  3255.         OffGadget(&RelGadget,ControlWindow,NULL);
  3256.         OffGadget(&MyAddGadget,ControlWindow,NULL);
  3257.         OffGadget(&DelGadget,ControlWindow,NULL);
  3258.         OffGadget(&LinkGadget,ControlWindow,NULL);
  3259.         OffGadget(&UnlinkGadget,ControlWindow,NULL);
  3260.         OffGadget(&NoneGadget,ControlWindow,NULL);
  3261.         OffGadget(&stGadget,ControlWindow,NULL);
  3262.         OffGadget(&prevGadget,ControlWindow,NULL);
  3263.         OffGadget(&gotoGadget,ControlWindow,NULL);
  3264.         OffGadget(&nextGadget,ControlWindow,NULL);
  3265.         OffGadget(&lastGadget,ControlWindow,NULL);
  3266.         // Wait pointer
  3267.         SetPointer(ControlWindow, BusyPointerData, 16, 16, -6, 0);
  3268.     }
  3269.     if (Pic1_Open) {
  3270.         // Turn verify off
  3271.         IDCMPFlags = IDCMP_IDCMPUPDATE | IDCMP_GADGETUP | IDCMP_GADGETDOWN |
  3272.                          IDCMP_NEWSIZE | IDCMP_MOUSEBUTTONS | IDCMP_MOUSEMOVE |
  3273.                          IDCMP_MENUPICK | IDCMP_CLOSEWINDOW | IDCMP_MENUHELP | IDCMP_RAWKEY | IDCMP_VANILLAKEY |
  3274.                          IDCMP_ACTIVEWINDOW | IDCMP_INACTIVEWINDOW | IDCMP_CHANGEWINDOW |
  3275.                          IDCMP_GADGETHELP | IDCMP_MOUSEMOVE;
  3276.         ModifyIDCMP(Pic1.Win,IDCMPFlags);
  3277.         Pic1.Win->Flags |= WFLG_REPORTMOUSE;
  3278.         // All 3 menus off
  3279. //        OffMenu(Pic1.Win,FULLMENUNUM(0,NOITEM,NOSUB));    // These are now shared menus
  3280. //        OffMenu(Pic1.Win,FULLMENUNUM(1,NOITEM,NOSUB));
  3281. //        OffMenu(Pic1.Win,FULLMENUNUM(2,NOITEM,NOSUB));
  3282.         // Wait pointer
  3283.         SetPointer(Pic1.Win, BusyPointerData, 16, 16, -6, 0);
  3284.         // all gadgets off
  3285.         SetGadgetAttrs(Pic1.Lgad,Pic1.Win,0,GA_Disabled,TRUE,TAG_END);
  3286.         SetGadgetAttrs(Pic1.Ugad,Pic1.Win,0,GA_Disabled,TRUE,TAG_END);
  3287.         SetGadgetAttrs(Pic1.Dgad,Pic1.Win,0,GA_Disabled,TRUE,TAG_END);
  3288.         SetGadgetAttrs(Pic1.Rgad,Pic1.Win,0,GA_Disabled,TRUE,TAG_END);
  3289.         SetGadgetAttrs(Pic1.SideGad,Pic1.Win,0,GA_Disabled,TRUE,TAG_END);
  3290.         SetGadgetAttrs(Pic1.BotGad,Pic1.Win,0,GA_Disabled,TRUE,TAG_END);
  3291.         RefreshGadgets(Pic1.BotGad,Pic1.Win,NULL);
  3292.     }
  3293.     if (Pic2_Open) {
  3294.         // Turn verify off
  3295.         IDCMPFlags = IDCMP_IDCMPUPDATE | IDCMP_GADGETUP | IDCMP_GADGETDOWN |
  3296.                          IDCMP_NEWSIZE | IDCMP_MOUSEBUTTONS | IDCMP_MOUSEMOVE |
  3297.                          IDCMP_MENUPICK | IDCMP_CLOSEWINDOW | IDCMP_MENUHELP | IDCMP_RAWKEY | IDCMP_VANILLAKEY |
  3298.                          IDCMP_ACTIVEWINDOW | IDCMP_INACTIVEWINDOW | IDCMP_CHANGEWINDOW |
  3299.                          IDCMP_GADGETHELP | IDCMP_MOUSEMOVE;
  3300.         ModifyIDCMP(Pic2.Win,IDCMPFlags);
  3301.         Pic2.Win->Flags |= WFLG_REPORTMOUSE;
  3302.         // All 3 menus off
  3303. //        OffMenu(Pic2.Win,FULLMENUNUM(0,NOITEM,NOSUB));    // These are now shared menus
  3304. //        OffMenu(Pic2.Win,FULLMENUNUM(1,NOITEM,NOSUB));
  3305. //        OffMenu(Pic2.Win,FULLMENUNUM(2,NOITEM,NOSUB));
  3306.         // Wait pointer
  3307.         SetPointer(Pic2.Win, BusyPointerData, 16, 16, -6, 0);
  3308.         // all gadgets off
  3309.         SetGadgetAttrs(Pic2.Lgad,Pic2.Win,0,GA_Disabled,TRUE,TAG_END);
  3310.         SetGadgetAttrs(Pic2.Ugad,Pic2.Win,0,GA_Disabled,TRUE,TAG_END);
  3311.         SetGadgetAttrs(Pic2.Dgad,Pic2.Win,0,GA_Disabled,TRUE,TAG_END);
  3312.         SetGadgetAttrs(Pic2.Rgad,Pic2.Win,0,GA_Disabled,TRUE,TAG_END);
  3313.         SetGadgetAttrs(Pic2.SideGad,Pic2.Win,0,GA_Disabled,TRUE,TAG_END);
  3314.         SetGadgetAttrs(Pic2.BotGad,Pic2.Win,0,GA_Disabled,TRUE,TAG_END);
  3315.         RefreshGadgets(Pic2.BotGad,Pic2.Win,NULL);
  3316.     }
  3317.     /* Disable gadgets in the Info window
  3318.      * Do not disable the GetFile gadgets
  3319.      * as it causes enforcer hits
  3320.      */
  3321.     if (TSMorphWnd) {
  3322.     //    GT_SetGadgetAttrs(TSMorphGadgets[GDX_GetFile1],TSMorphWnd,NULL,GA_Disabled,TRUE,TAG_END);    // GetFile gadgets do not like being disabled
  3323.     //    GT_SetGadgetAttrs(TSMorphGadgets[GDX_GetFile2],TSMorphWnd,NULL,GA_Disabled,TRUE,TAG_END);
  3324.     //    GT_SetGadgetAttrs(TSMorphGadgets[GDX_GetFileOne],TSMorphWnd,NULL,GA_Disabled,TRUE,TAG_END);
  3325.     //    GT_SetGadgetAttrs(TSMorphGadgets[GDX_GetFileTwo],TSMorphWnd,NULL,GA_Disabled,TRUE,TAG_END);
  3326.         GT_SetGadgetAttrs(TSMorphGadgets[GDX_EditPoints],TSMorphWnd,NULL,GA_Disabled,TRUE,TAG_END);
  3327.         GT_SetGadgetAttrs(TSMorphGadgets[GDX_SinglePicture],TSMorphWnd,NULL,GA_Disabled,TRUE,TAG_END);
  3328.     //    GT_SetGadgetAttrs(TSMorphGadgets[GDX_GetSaveName],TSMorphWnd,NULL,GA_Disabled,TRUE,TAG_END);
  3329.         GT_SetGadgetAttrs(TSMorphGadgets[GDX_FileOne],TSMorphWnd,NULL,GA_Disabled,TRUE,TAG_END);
  3330.         GT_SetGadgetAttrs(TSMorphGadgets[GDX_FileTwo],TSMorphWnd,NULL,GA_Disabled,TRUE,TAG_END);
  3331.         GT_SetGadgetAttrs(TSMorphGadgets[GDX_File241],TSMorphWnd,NULL,GA_Disabled,TRUE,TAG_END);
  3332.         GT_SetGadgetAttrs(TSMorphGadgets[GDX_File242],TSMorphWnd,NULL,GA_Disabled,TRUE,TAG_END);
  3333.         GT_SetGadgetAttrs(TSMorphGadgets[GDX_Frames],TSMorphWnd,NULL,GA_Disabled,TRUE,TAG_END);
  3334.         GT_SetGadgetAttrs(TSMorphGadgets[GDX_Name],TSMorphWnd,NULL,GA_Disabled,TRUE,TAG_END);
  3335.         GT_SetGadgetAttrs(TSMorphGadgets[GDX_Start],TSMorphWnd,NULL,GA_Disabled,TRUE,TAG_END);
  3336.         // Both menus off
  3337.         OffMenu(TSMorphWnd,FULLMENUNUM(0,NOITEM,NOSUB));
  3338.         OffMenu(TSMorphWnd,FULLMENUNUM(1,NOITEM,NOSUB));
  3339.         // Wait pointer
  3340.         SetPointer(TSMorphWnd, BusyPointerData, 16, 16, -6, 0);
  3341.     }
  3342. }
  3343.  
  3344. /* Enable all windows,
  3345.  * menus, pointers,
  3346.  * gadgets etc.
  3347.  */
  3348. void
  3349. EnableWindows(void) {
  3350.     LONG Frames,Start;
  3351.     if (TSMorphWnd) {
  3352.         Frames = GetNumber(TSMorphGadgets[GDX_Frames]);
  3353.         Start = GetNumber(TSMorphGadgets[GDX_Start]);
  3354.     }
  3355.     if (ControlWindow) {
  3356.         // Menus and gadgets on
  3357.         OnMenu(ControlWindow,FULLMENUNUM(M_PROJECT,NOITEM,NOSUB));
  3358.         OnMenu(ControlWindow,FULLMENUNUM(M_EDIT,NOITEM,NOSUB));
  3359.         OnMenu(ControlWindow,FULLMENUNUM(M_SETTINGS,NOITEM,NOSUB));
  3360.         OnGadget(&OneGadget,ControlWindow,NULL);
  3361.         OnGadget(&TwoGadget,ControlWindow,NULL);
  3362.         OnGadget(&RelGadget,ControlWindow,NULL);
  3363.         OnGadget(&MyAddGadget,ControlWindow,NULL);
  3364.         OnGadget(&DelGadget,ControlWindow,NULL);
  3365.         OnGadget(&LinkGadget,ControlWindow,NULL);
  3366.         OnGadget(&UnlinkGadget,ControlWindow,NULL);
  3367.         OnGadget(&NoneGadget,ControlWindow,NULL);
  3368.         if ((SinglePicture == 2) || (SinglePicture == 3)) {
  3369.             if (FrameNumber > Start) {
  3370.                 OnGadget(&stGadget,ControlWindow,NULL);
  3371.                 OnGadget(&prevGadget,ControlWindow,NULL);
  3372.                 OnMenu(ControlWindow,FULLMENUNUM(M_EDIT,MM_FRAME,MI_FIRST));
  3373.                 OnMenu(ControlWindow,FULLMENUNUM(M_EDIT,MM_FRAME,MI_PREV));
  3374.             }
  3375.             else {
  3376.                 OffMenu(ControlWindow,FULLMENUNUM(M_EDIT,MM_FRAME,MI_FIRST));
  3377.                 OffMenu(ControlWindow,FULLMENUNUM(M_EDIT,MM_FRAME,MI_PREV));
  3378.             }
  3379.             if (FrameNumber < (Start+Frames-1)) {
  3380.                 OnGadget(&nextGadget,ControlWindow,NULL);
  3381.                 OnGadget(&lastGadget,ControlWindow,NULL);
  3382.                 OnMenu(ControlWindow,FULLMENUNUM(M_EDIT,MM_FRAME,MI_NEXT));
  3383.                 OnMenu(ControlWindow,FULLMENUNUM(M_EDIT,MM_FRAME,MI_LAST));
  3384.             }
  3385.             else {
  3386.                 OffMenu(ControlWindow,FULLMENUNUM(M_EDIT,MM_FRAME,MI_NEXT));
  3387.                 OffMenu(ControlWindow,FULLMENUNUM(M_EDIT,MM_FRAME,MI_LAST));
  3388.             }
  3389.             if (Frames > 1) {
  3390.                 OnMenu(ControlWindow,FULLMENUNUM(M_EDIT,MM_FRAME,MI_GOTO));
  3391.                 OnGadget(&gotoGadget,ControlWindow,NULL);
  3392.             }
  3393.             else {
  3394.                 OffMenu(ControlWindow,FULLMENUNUM(M_EDIT,MM_FRAME,MI_GOTO));
  3395.             }
  3396.         }
  3397.         else {
  3398.             OffMenu(ControlWindow,FULLMENUNUM(M_EDIT,MM_FRAME,NOSUB));
  3399.         }
  3400.     }
  3401.     if (Pic1_Open) {
  3402.         // verify, menus and gadgets on
  3403.         IDCMPFlags = IDCMP_IDCMPUPDATE | IDCMP_GADGETUP | IDCMP_GADGETDOWN |
  3404.                          IDCMP_NEWSIZE | IDCMP_MOUSEBUTTONS | IDCMP_MOUSEMOVE |
  3405.                          IDCMP_MENUPICK | IDCMP_CLOSEWINDOW | IDCMP_MENUVERIFY |
  3406.                          IDCMP_MENUHELP | IDCMP_RAWKEY | IDCMP_VANILLAKEY |
  3407.                          IDCMP_ACTIVEWINDOW | IDCMP_INACTIVEWINDOW | IDCMP_CHANGEWINDOW |
  3408.                          IDCMP_GADGETHELP;
  3409.         ModifyIDCMP(Pic1.Win,IDCMPFlags);
  3410.         Pic1.Win->Flags |= WFLG_REPORTMOUSE;
  3411. //        OnMenu(Pic1.Win,FULLMENUNUM(0,NOITEM,NOSUB));    // These are now shared menus
  3412. //        OnMenu(Pic1.Win,FULLMENUNUM(1,NOITEM,NOSUB));
  3413. //        OnMenu(Pic1.Win,FULLMENUNUM(2,NOITEM,NOSUB));
  3414.         SetGadgetAttrs(Pic1.Lgad,Pic1.Win,0,GA_Disabled,FALSE,TAG_END);
  3415.         SetGadgetAttrs(Pic1.Ugad,Pic1.Win,0,GA_Disabled,FALSE,TAG_END);
  3416.         SetGadgetAttrs(Pic1.Dgad,Pic1.Win,0,GA_Disabled,FALSE,TAG_END);
  3417.         SetGadgetAttrs(Pic1.Rgad,Pic1.Win,0,GA_Disabled,FALSE,TAG_END);
  3418.         SetGadgetAttrs(Pic1.SideGad,Pic1.Win,0,GA_Disabled,FALSE,TAG_END);
  3419.         SetGadgetAttrs(Pic1.BotGad,Pic1.Win,0,GA_Disabled,FALSE,TAG_END);
  3420.         RefreshGadgets(Pic1.BotGad,Pic1.Win,NULL);
  3421.     }
  3422.     if (Pic2_Open) {
  3423.         // verify, menus and gadgets on
  3424.         IDCMPFlags = IDCMP_IDCMPUPDATE | IDCMP_GADGETUP | IDCMP_GADGETDOWN |
  3425.                          IDCMP_NEWSIZE | IDCMP_MOUSEBUTTONS | IDCMP_MOUSEMOVE |
  3426.                          IDCMP_MENUPICK | IDCMP_CLOSEWINDOW | IDCMP_MENUVERIFY |
  3427.                          IDCMP_MENUHELP | IDCMP_RAWKEY | IDCMP_VANILLAKEY |
  3428.                          IDCMP_ACTIVEWINDOW | IDCMP_INACTIVEWINDOW | IDCMP_CHANGEWINDOW |
  3429.                          IDCMP_GADGETHELP;
  3430.         ModifyIDCMP(Pic2.Win,IDCMPFlags);
  3431.         Pic2.Win->Flags |= WFLG_REPORTMOUSE;
  3432. //        OnMenu(Pic2.Win,FULLMENUNUM(0,NOITEM,NOSUB));    // These are now shared menus
  3433. //        OnMenu(Pic2.Win,FULLMENUNUM(1,NOITEM,NOSUB));
  3434. //        OnMenu(Pic2.Win,FULLMENUNUM(2,NOITEM,NOSUB));
  3435.         SetGadgetAttrs(Pic2.Lgad,Pic2.Win,0,GA_Disabled,FALSE,TAG_END);
  3436.         SetGadgetAttrs(Pic2.Ugad,Pic2.Win,0,GA_Disabled,FALSE,TAG_END);
  3437.         SetGadgetAttrs(Pic2.Dgad,Pic2.Win,0,GA_Disabled,FALSE,TAG_END);
  3438.         SetGadgetAttrs(Pic2.Rgad,Pic2.Win,0,GA_Disabled,FALSE,TAG_END);
  3439.         SetGadgetAttrs(Pic2.SideGad,Pic2.Win,0,GA_Disabled,FALSE,TAG_END);
  3440.         SetGadgetAttrs(Pic2.BotGad,Pic2.Win,0,GA_Disabled,FALSE,TAG_END);
  3441.         RefreshGadgets(Pic2.BotGad,Pic2.Win,NULL);
  3442.     }
  3443.     if (TSMorphWnd) {
  3444.         // Set pointer for Control and both image windows
  3445.         SetMyPointer();
  3446.         /* Turn relevant gadgets back on
  3447.          * Do not enable GetFile gadgets as it causes enforcer hits
  3448.          */
  3449.         if (!ControlWindow) {
  3450.     //        GT_SetGadgetAttrs(TSMorphGadgets[GDX_GetFileOne],TSMorphWnd,NULL,GA_Disabled,FALSE,TAG_END);    // GetFile gadgets do not like being disabled
  3451.     //        GT_SetGadgetAttrs(TSMorphGadgets[GDX_GetFileTwo],TSMorphWnd,NULL,GA_Disabled,FALSE,TAG_END);
  3452.             GT_SetGadgetAttrs(TSMorphGadgets[GDX_FileOne],TSMorphWnd,NULL,GA_Disabled,FALSE,TAG_END);
  3453.             GT_SetGadgetAttrs(TSMorphGadgets[GDX_FileTwo],TSMorphWnd,NULL,GA_Disabled,FALSE,TAG_END);
  3454.             GT_SetGadgetAttrs(TSMorphGadgets[GDX_SinglePicture],TSMorphWnd,NULL,GA_Disabled,FALSE,TAG_END);
  3455.             GT_SetGadgetAttrs(TSMorphGadgets[GDX_Frames],TSMorphWnd,NULL,GA_Disabled,FALSE,TAG_END);
  3456.             GT_SetGadgetAttrs(TSMorphGadgets[GDX_Start],TSMorphWnd,NULL,GA_Disabled,FALSE,TAG_END);
  3457.         }
  3458.         GT_SetGadgetAttrs(TSMorphGadgets[GDX_EditPoints],TSMorphWnd,NULL,GA_Disabled,FALSE,TAG_END);
  3459.     //    GT_SetGadgetAttrs(TSMorphGadgets[GDX_GetFile1],TSMorphWnd,NULL,GA_Disabled,FALSE,TAG_END);
  3460.     //    GT_SetGadgetAttrs(TSMorphGadgets[GDX_GetFile2],TSMorphWnd,NULL,GA_Disabled,FALSE,TAG_END);
  3461.     //    GT_SetGadgetAttrs(TSMorphGadgets[GDX_GetSaveName],TSMorphWnd,NULL,GA_Disabled,FALSE,TAG_END);
  3462.         GT_SetGadgetAttrs(TSMorphGadgets[GDX_File241],TSMorphWnd,NULL,GA_Disabled,FALSE,TAG_END);
  3463.         GT_SetGadgetAttrs(TSMorphGadgets[GDX_File242],TSMorphWnd,NULL,GA_Disabled,FALSE,TAG_END);
  3464.         GT_SetGadgetAttrs(TSMorphGadgets[GDX_Name],TSMorphWnd,NULL,GA_Disabled,FALSE,TAG_END);
  3465.         // Menus back on
  3466.         OnMenu(TSMorphWnd,FULLMENUNUM(0,NOITEM,NOSUB));
  3467.         OnMenu(TSMorphWnd,FULLMENUNUM(1,NOITEM,NOSUB));
  3468.         // Pointer back on
  3469.         ClearPointer(TSMorphWnd);
  3470.     }
  3471.     if (TSMorphWnd) {
  3472.         GT_SetGadgetAttrs(TSMorphGadgets[GDX_Help],TSMorphWnd,NULL,
  3473.                             GTTX_Text,"Ready", TAG_END );
  3474.     }
  3475. }
  3476.